--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/pcdbms/udbms/UD_CURS.CPP Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1210 @@
+// Copyright (c) 1998-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 "UD_STD.H"
+
+// Class RDbRowSet
+
+/** Resets the rowset.
+
+For a Table, this just sets the rowset cursor to the beginning position.
+
+For an SQL view, this discards any evaluated rows and returns the cursor to
+the beginning. The view then requires reevaluation.
+
+The Store Database implementation requires this function to be called in order
+to recover an open rowset object after the database has been rolled back.
+The rowset does not need to be closed in this situation.
+
+If a rowset object requires a reset, then all row functions return or leave
+with KErrNotReady. */
+EXPORT_C void RDbRowSet::Reset()
+ {
+ iCursor->Reset();
+ }
+
+/** Closes the rowset and releases any owned resources. It is safe to close a rowset
+object which is not open. */
+EXPORT_C void RDbRowSet::Close()
+ {
+ iCursor.Close();
+ }
+
+/** Returns the number of rows available in a rowset.
+
+This can take some time to complete, and a parameter can be passed to request
+a quick but not always thorough count of the rows.
+
+For SQL views, the value returned depends on the evaluation window being used
+by the view. If there is an evaluation window this function will always return
+the number of rows available in the window, not the total number which could
+be returned by the query.
+
+@param anAccuracy This specifies whether to ensure that an accurate count
+is returned, or to give up if this value is not readily available. The default
+is to ensure an accurate count.
+@return The number of rows available in the rowset, or KDbUndefinedCount if
+EQuick was specified and the count was not available.
+
+@capability Note For a secure shared database, the caller must satisfy either the read
+ or the write access policy for the table.
+*/
+EXPORT_C TInt RDbRowSet::CountL(TAccuracy aAccuracy) const
+ {
+ return iCursor->CountL(aAccuracy);
+ }
+
+/** Tests whether there are any rows in the rowset. This is often faster than testing
+whether CountL()==0.
+
+@return ETrue if there are no rows available in the rowset, EFalse if there
+are one or more.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TBool RDbRowSet::IsEmptyL() const
+ {
+ if (AtRow())
+ return EFalse;
+ TInt count=CountL(EQuick);
+ if (count!=KDbUndefinedCount)
+ return count==0;
+ TDbBookmark mark=Bookmark();
+ CDbCursor& cursor=*iCursor;
+ TBool hasRow=cursor.GotoL(EFirst);
+ cursor.GotoL(mark.iMark);
+ return !hasRow;
+ }
+
+/** Returns the entire column set for the rowset. This can be used to discover
+column ordinals for named columns in this rowset.
+
+The function leaves with KErrNoMemory if there is not enough memory to carry
+out the operation.
+
+@return The column set object which describes this rowset structure. The caller
+should delete it when it is no longer required. */
+EXPORT_C CDbColSet* RDbRowSet::ColSetL() const
+ {
+ CDbColSet* cs=CDbColSet::NewLC();
+ iCursor->ColumnsL(*cs);
+ CleanupStack::Pop();
+ return cs;
+ }
+
+/** Returns the number of columns which are defined in this rowset.
+
+@return The number of columns which are defined in this rowset. */
+EXPORT_C TInt RDbRowSet::ColCount() const
+ {
+ return iCursor->ColumnCount();
+ }
+
+/** Returns the type of a column in the rowset.
+
+@param aCol The column ordinal for which the column type is required. Column
+ordinals range from 1 to ColCount().
+@return The type of the column aCol. */
+EXPORT_C TDbColType RDbRowSet::ColType(TDbColNo aColNo) const
+ {
+ return iCursor->ColumnType(aColNo);
+ }
+
+/** Returns the definition of a column in the rowset.
+
+@param aCol The column ordinal for which the column definition is required.
+Column ordinals range from 1 to ColCount().
+@return The definition of the column aCol. */
+EXPORT_C TDbCol RDbRowSet::ColDef(TDbColNo aColNo) const
+ {
+ TDbCol col;
+ iCursor->ColumnDef(col,aColNo);
+ return col;
+ }
+
+/** Tests whether the cursor is on a row.
+
+One of the following is true:
+
+the rowset is currently updating a row
+
+the rowset is currently inserting a row
+
+GetL() can be called to retrieve the row
+
+@return ETrue if the cursor is on a valid row; EFalse, otherwise. */
+EXPORT_C TBool RDbRowSet::AtRow() const
+ {
+ return iCursor->AtRow();
+ }
+
+/** Tests whether the cursor is at the beginning of the rowset.
+
+@return ETrue if the cursor is at the beginning, otherwise EFalse. */
+EXPORT_C TBool RDbRowSet::AtBeginning() const
+ {
+ return iCursor->AtBeginning();
+ }
+
+/** Tests whether the cursor is at the end of the rowset.
+
+@return ETrue if the cursor is at the end, otherwise EFalse. */
+EXPORT_C TBool RDbRowSet::AtEnd() const
+ {
+ return iCursor->AtEnd();
+ }
+
+/** Moves the cursor to a specified position.
+
+This is invoked by Beginning(), End(), FirstL(), LastL(), NextL() and PreviousL()
+to navigate the cursor. See those functions for descriptions of how the cursor
+behaves given different position specifications.
+
+@param aPosition Specifies the position to move the cursor to.
+@return ETrue if the cursor is now at a row, EFalse if it is at the beginning
+or end.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TBool RDbRowSet::GotoL(TPosition aPosition)
+ {
+ return iCursor->GotoL(aPosition);
+ }
+
+/** Gets the bookmark for the current cursor position. Bookmarks cannot be extracted
+when the rowset is updating or inserting a row.
+
+The Store Database implementation allows bookmarks to be extracted for any
+cursor position including the beginning and end.
+
+@return A bookmark which can be used to return to the current position using
+the GotoL() function.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TDbBookmark RDbRowSet::Bookmark() const
+ {
+ TDbBookmark mark;
+ iCursor->Bookmark(mark.iMark);
+ return mark;
+ }
+
+/** Goes to a previously bookmarked position in a rowset.
+
+The Store Database implements bookmarks which are valid in any rowset based
+on the same table or generated by the same query, and which persist across
+transaction boundaries.
+
+@param aMark The bookmark to return to. This should have been returned by
+a previous call to Bookmark() on this or an equivalent rowset object.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::GotoL(const TDbBookmark& aMark)
+ {
+ iCursor->GotoL(aMark.iMark);
+ }
+
+/** Gets the current row data for access using the column extractor functions.
+The cursor must be positioned at a valid row.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::GetL()
+ {
+ iCursor->GetL();
+ }
+
+/** Inserts a new row into the rowset. All auto-increment columns will be initialised
+with their new values, all other columns will be initialised to NULL values.
+If no client-begun transaction is in progress, this function begins an automatic
+transaction, which is committed by PutL().
+
+After the column values have been set using the SetColL() functions, the row
+can be written to the database using PutL().
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::InsertL()
+ {
+ iCursor->InsertL(CDbCursor::EClear);
+ }
+
+/** Inserts a copy of the current row into the rowset. All auto-increment columns
+will be given a new value (as for InsertL()), the other columns will copy
+their values from the cursor's current row. If no client-begun transaction
+is in progress, this function begins an automatic transaction, which is committed
+by PutL().
+
+After the column values have been modified using the SetColL() functions,
+the row can be written to the database using PutL().
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::InsertCopyL()
+ {
+ iCursor->InsertL(CDbCursor::ECopy);
+ }
+
+/** Prepares the current row for update. If no client-begun transaction is in progress,
+this function begins an automatic transaction, which is committed by PutL().
+
+After the column values have been modified using the SetColL() functions,
+the row can be written back to the database using PutL().
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::UpdateL()
+ {
+ iCursor->UpdateL();
+ }
+
+/** Completes the update or insertion of a row.
+
+First the new row data is validated:
+
+not-null columns are checked to be not NULL
+
+numerical columns are checked to be in range for their type
+
+variable length columns are checked to not exceed their maximum length
+
+unique index keys are checked to ensure uniqueness is not violated
+
+Note that modifying auto-increment columns is not prevented by DBMS.
+
+Following validation the data is written to the database and any affected
+indexes are updated. On successful completion of the write, PutL() will then
+commit any automatic transaction.
+
+The cursor is left positioned on the updated or inserted row — where this
+lies in the rowset is not always well defined. To return to the row which
+was current prior to the update or insertion, a bookmark can be used.
+
+In the Store Database implementation the written row is located in the rowset
+as follows:
+
+Tables without an active index will leave updated rows in the same location
+and append new rows to the end of the rowset.
+
+Tables with an active index place the row according to the active index ordering.
+
+SQL views without an evaluation window will place it according to the rowset
+ordering. The row may subsequently disappear if it does not match the WHERE
+clause of the SQL query.
+
+SQL views with a full evaluation window will leave updated rows in the same
+location and append new rows to the end of the rowset. Re-evaluation may cause
+the row to disappear if it does not match the WHERE clause of the SQL query.
+
+SQL views with a partial evaluation window will leave updated rows in the
+same location, new rows are not added to the window and navigation from the
+new row is undefined. Further navigation and evaluation of the partial window
+will place the rows in the correct location according to the query.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::PutL()
+ {
+ iCursor->PutL();
+ }
+
+/** Deletes the current row in a rowset. The rowset must not currently be updating
+or inserting the row.
+
+The rowset cursor is left positioned at the "hole" left by the deletion of
+the current row. Navigation to the next or previous row will have the same
+effect as if this row had not been deleted. Once the cursor has been moved
+from the "hole" it will disappear from the rowset.
+
+If the client has not begun a transaction, this function will use an automatic
+transaction to update the rowset.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::DeleteL()
+ {
+ iCursor->DeleteL();
+ }
+
+/** Cancels the update or insertion of a row, or recovers the rowset if PutL()
+fails. The cursor will return to the location prior to starting the update
+or insertion. It is also safe to call this function when the rowset object
+is not updating or inserting a row, in which case it does nothing.
+
+In the Store database implementation, if this is called to abort a row update
+or insertion before PutL() is called or during row validation in PutL(), all
+the changes are discarded without requiring a transaction rollback and the
+rowset to be Reset(). */
+EXPORT_C void RDbRowSet::Cancel()
+ {
+ iCursor->Cancel();
+ }
+
+//
+// Checks for valid Cursor and column ID
+//
+CDbCursor& RDbRowSet::CheckCol(TDbColNo aCol) const
+ {
+ CDbCursor& cr=*iCursor;
+ __ASSERT_ALWAYS(aCol>0&&aCol<=cr.ColumnCount(),Panic(EDbInvalidColumn));
+ return cr;
+ }
+
+//
+// Checks for valid Cursor, column ID and type
+//
+TDbColumnC RDbRowSet::ColumnC(TDbColNo aCol,TDbColType aType) const
+ {
+ CDbCursor& cr=*iCursor;
+ TDbColType cType=cr.ColumnType(aCol);
+ if (cType!=aType)
+ { // not an exact match
+ if (cType>aType)
+ Panic(EDbWrongType); // extraction type is narrower
+ else if (!IsIntegral(cType))
+ Panic(EDbWrongType); // type is non-integral
+ else if (IsSigned(cType) && IsUnsigned(aType))
+ Panic(EDbWrongType); // cannot get signed column as unsigned
+ }
+ return cr.ColumnC(aCol);
+ }
+
+TDbColumn RDbRowSet::Column(TDbColNo aCol,TDbColType aType)
+ {
+ CDbCursor& cr=*iCursor;
+ __ASSERT_ALWAYS(cr.ColumnType(aCol)==aType,Panic(EDbWrongType));
+ return cr.Column(aCol);
+ }
+
+/** Gets the size in bytes of a column value. This can be used for all column types,
+including Long columns. NULL columns return a size of 0.
+
+Note:
+
+This may yield unexpected results for small numerical column types as they
+are stored in memory as 32-bit values.
+
+@param aCol The column ordinal of the column to check.
+@return The length in bytes of column aCol's value. */
+EXPORT_C TInt RDbRowSet::ColSize(TDbColNo aCol) const
+ {
+ return iCursor->ColumnSize(aCol);
+ }
+
+/** Gets the length of a column value. As compared with ColSize(), this returns
+the number of "units" in the column:
+
+NULL columns have a length of 0
+
+non-NULL numerical and date-time columns have a length of 1
+
+for Text columns the length is the character count
+
+for Binary columns the length is the byte count
+
+@param aCol The column ordinal of the column to check.
+@return The length in "units" of column aCol's value. */
+EXPORT_C TInt RDbRowSet::ColLength(TDbColNo aCol) const
+ {
+ TInt size=ColSize(aCol);
+ switch (iCursor()->ColumnType(aCol))
+ {
+ case EDbColText8:
+ case EDbColLongText8:
+ case EDbColBinary:
+ case EDbColLongBinary:
+ break;
+ case EDbColText16:
+ case EDbColLongText16:
+ if (size>0)
+ size>>=1;
+ break;
+ default:
+ if (size)
+ size=1;
+ break;
+ }
+ return size;
+ }
+
+/** Extracts a TInt8 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TInt8 RDbRowSet::ColInt8(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColInt8).Int8();
+ }
+
+/** Extracts a TInt16 or TInt8 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TInt16 RDbRowSet::ColInt16(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColInt16).Int16();
+ }
+
+/** Extracts a TInt32, TInt16 or TInt8 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TInt32 RDbRowSet::ColInt32(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColInt32).Int32();
+ }
+
+/** Extracts a TInt64 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TInt64 RDbRowSet::ColInt64(TDbColNo aCol) const
+ {
+ CDbCursor& cr=*iCursor;
+ TDbColumnC c=cr.ColumnC(aCol);
+ TDbColType t=cr.ColumnType(aCol);
+ if (t==EDbColInt64)
+ return c.Int64();
+ if (t>EDbColInt64)
+ Panic(EDbWrongType);
+ if (IsSigned(t))
+ return TInt(c.Int32());
+ return TUint(c.Uint32());
+ }
+
+/** Extracts a Uint8 or Bit column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TUint8 RDbRowSet::ColUint8(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColUint8).Uint8();
+ }
+
+/** Extracts a Uint16, Uint8 or Bit column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TUint16 RDbRowSet::ColUint16(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColUint16).Uint16();
+ }
+
+/** Extracts a Uint32, Uint16, Uint8 or Bit column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TUint32 RDbRowSet::ColUint32(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColUint32).Uint32();
+ }
+
+/** Extracts a TReal32 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TReal32 RDbRowSet::ColReal32(TDbColNo aCol) const __SOFTFP
+ {
+ return ColumnC(aCol,EDbColReal32).Real32();
+ }
+
+/** Extracts a TReal64 column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. */
+EXPORT_C TReal64 RDbRowSet::ColReal64(TDbColNo aCol) const __SOFTFP
+ {
+ return ColumnC(aCol,EDbColReal64).Real64();
+ }
+
+/** Extracts a TTime column value.
+
+@param aCol The column ordinal of the column to extract.
+@return The value of column aCol. TTime may be either local time or universal time.
+DBMS doesn't interpret the value of TTime, it is left up to the user to know which has been used.*/
+EXPORT_C TTime RDbRowSet::ColTime(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColDateTime).Time();
+ }
+
+/** Extracts any column type, except Long columns, as binary data.
+Can handle any type of non-long column
+
+@param aCol The column ordinal of the column to extract.
+@return A descriptor of column aCol's value. */
+EXPORT_C TPtrC8 RDbRowSet::ColDes8(TDbColNo aCol) const
+ {
+ CDbCursor& cr=*iCursor;
+ __ASSERT_ALWAYS(!IsLong(cr.ColumnType(aCol)),Panic(EDbWrongType));
+ return cr.ColumnC(aCol).PtrC8();
+ }
+
+/** Extracts a column as Unicode text.
+
+@param aCol The column ordinal of the column to extract
+@return A descriptor of column aCol's value. */
+EXPORT_C TPtrC16 RDbRowSet::ColDes16(TDbColNo aCol) const
+ {
+ return ColumnC(aCol,EDbColText16).PtrC16();
+ }
+
+/** Extracts a Text column value. The column type must match the default descriptor
+type to use this extractor, ie. it must be equal to EDbColText.
+
+@param aCol The column ordinal of the column to extract.
+@return A descriptor of column aCol's value. */
+EXPORT_C TPtrC RDbRowSet::ColDes(TDbColNo aCol) const
+ {
+ return ColDes16(aCol);
+ }
+
+/** Use this function to set the value of a column to NULL.
+
+@param aCol The column ordinal of the column to set to NULL.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbRowSet::SetColNullL(TDbColNo aCol)
+ {
+ iCursor->SetNullL(aCol);
+ }
+
+/** Sets a TInt32, TInt16 or TInt8 column value.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TInt32 aValue)
+ {
+ CDbCursor& cr=*iCursor;
+ TDbColType t=cr.ColumnType(aCol);
+ if (t<EDbColInt64)
+ { // set any <= 32-bit integral type
+ if (IsSigned(t))
+ {
+ cr.Column(aCol).SetL(aValue);
+ return;
+ }
+ if (aValue>=0)
+ { // check the domain for unsigned columns
+ cr.Column(aCol).SetL(aValue);
+ return;
+ }
+ }
+ Panic(EDbWrongType);
+ }
+
+/** Sets a TInt64 column value.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TInt64 aValue)
+ {
+ CDbCursor& cr=*iCursor;
+ TDbColumn c=cr.Column(aCol);
+ TDbColType t=cr.ColumnType(aCol);
+ if (t==EDbColInt64)
+ { // exact match
+ c.SetL(aValue);
+ return;
+ }
+ if (t<EDbColInt64)
+ {
+ TInt32 l = I64LOW(aValue);
+ TInt32 h = I64HIGH(aValue);
+ if (IsSigned(t))
+ { // check the domain for signed 32-bit
+ if (h==l>>31) // sign-extend l gives aValue
+ {
+ c.SetL(l);
+ return;
+ }
+ } // invalid type, drop through to panic
+ else
+ { // check the domain for unsigned 32-bit
+ if (h==0)
+ { // zero extend l gives aValue
+ c.SetL(l); // in unsigned 32 bit range
+ return;
+ }
+ } // invalid type, drop through to panic
+ }
+ Panic(EDbWrongType);
+ }
+
+/** Sets a TUint32, TUint16, TUint8 or Bit column value.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TUint32 aValue)
+ {
+ CDbCursor& cr=*iCursor;
+ TDbColType t=cr.ColumnType(aCol);
+ if (t<EDbColInt64)
+ { // set any <= 32-bit integral type
+ if (IsUnsigned(t))
+ {
+ cr.Column(aCol).SetL(aValue);
+ return;
+ }
+ if (aValue<=TUint32(KMaxTInt))
+ { // check the domain for signed columns
+ cr.Column(aCol).SetL(aValue);
+ return;
+ }
+ }
+ Panic(EDbWrongType);
+ }
+
+/** Sets a TReal32 column value.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TReal32 aValue) __SOFTFP
+ {
+ Column(aCol,EDbColReal32).SetL(aValue);
+ }
+
+/** Sets a TReal64 column value.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TReal64 aValue) __SOFTFP
+ {
+ Column(aCol,EDbColReal64).SetL(aValue);
+ }
+
+/** Sets a TTime column value.
+
+TTime could be either local time or universal time.
+DBMS doesn't interpret the value of TTime, it is left up to the user to decide which should be used.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TTime aValue)
+ {
+ Column(aCol,EDbColDateTime).SetL(aValue);
+ }
+
+/** Sets a column value from an 8 bit descriptor. This function can also set the
+value of Long columns.
+
+Usually this is used to set a Text8 or LongText8 column from a non-Unicode
+text descriptor, but can be used for any column type: the data content is
+validated when the row is PutL().
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,const TDesC8 &aValue)
+ {
+ CDbCursor& c=*iCursor;
+ if (IsLong(c.ColumnType(aCol)))
+ {
+ RDbColWriteStream strm;
+ strm.OpenLC(*this,aCol);
+ strm.WriteL(aValue);
+ strm.CommitL();
+ CleanupStack::PopAndDestroy();
+ }
+ else
+ c.Column(aCol).SetL(aValue);
+ }
+
+/** Set a column value from Unicode text.
+
+@param aCol The column ordinal of the column to set.
+@param aValue The new column value. */
+EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,const TDesC16 &aValue)
+ {
+ CDbCursor& c=*iCursor;
+ if (c.ColumnType(aCol)==EDbColLongText16)
+ {
+ RDbColWriteStream strm;
+ strm.OpenLC(*this,aCol);
+ strm.WriteL(aValue);
+ strm.CommitL();
+ CleanupStack::PopAndDestroy();
+ }
+ else
+ Column(aCol,EDbColText16).SetL(aValue);
+ }
+
+/** Searches through a rowset for a row which fulfils an SQL search-condition.
+The search begins from the current position (which must be a valid row) and
+proceeds forwards or backwards through the available rows until it finds a
+match or runs out of rows.
+
+The cursor is positioned to the matching row (or beginning/end of set) on
+return.
+
+This is a brute-force approach to finding a row using an index for key-based
+retrieval on a Table rowset is a much faster but less flexible way of finding
+rows.
+
+@param aDirection Specifies which direction to search after testing the current
+row.
+@param aCriteria A query object containing an SQL search-condition to match
+against.
+@return If no match is found KErrNotFound is returned. Otherwise the number
+of rows navigated while finding a match, which may be 0 if the current row
+matches.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbRowSet::FindL(TDirection aDirection,TDbQuery aCriteria)
+ {
+ return iCursor->FindL(aDirection,aCriteria);
+ }
+
+/** Tests whether the current row in the rowset matches a previously compiled row
+constraint. The rowset must not currently be updating or inserting a row.
+
+@param aConstraint A row constraint object which must have been previously
+opened on this rowset object.
+@return ETrue if the current row fulfils the constraint, otherwise EFalse.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TBool RDbRowSet::MatchL(const RDbRowConstraint& aConstraint)
+ {
+ return iCursor->MatchL(*aConstraint.iConstraint);
+ }
+
+// Class RDbRowConstraint
+
+/** Compiles the specified SQL search-condition for matching against rows in the
+specified rowset. The text comparison supplied in aCriteria is used for all
+text columns in the constraint.
+
+@param aView The rowset to which the constraint will apply.
+@param aCriteria The SQL string and the text comparison mode for the constraint.
+@return KErrNone, if successful, otherwise one of the system-wide error codes.
+Specifically:KErrNotFound if a column name in the SQL query does not exist.KErrArgument
+if Invalid or unrecognised SQL syntax was used.KErrGeneral for a column type
+mismatch in a predicate in the SQL query or if a date-literal in the SQL query
+was invalid.KErrOverflow if a number-literal in the SQL query for an integral
+column was too large (did not fit in a 32-bit integral representation). This
+can also be one of the DBMS database error codes.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbRowConstraint::Open(const RDbRowSet& aView,TDbQuery aCriteria)
+ {
+ TRAPD(r,iConstraint=aView.iCursor->ConstraintL(aCriteria));
+ return r;
+ }
+
+/** Releases the resources used by the constraint before discarding the constraint
+object. */
+EXPORT_C void RDbRowConstraint::Close()
+ {
+ iConstraint.Close();
+ }
+
+// Class RDbColReadStream
+
+/** Opens the column with the specified ordinal in the specified current row in
+the rowset. The row must have previously been read into the rowset using RDbRowSet::GetL().
+
+@param aView The rowset which has the row and column to be read.
+@param aCol The column ordinal of the column to be read
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C void RDbColReadStream::OpenL(const RDbRowSet& aView,TDbColNo aCol)
+ {
+ Attach(aView.ColSourceL(aCol));
+ }
+
+/** Opens the column with the specified ordinal in the specified current row in
+the rowset and puts a pointer to the column on the cleanup stack.
+
+The row must have previously been read into the rowset using RDbRowSet::GetL().
+
+@param aView The rowset which has the row and column to be read.
+@param aCol The column ordinal of the column to be read.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C void RDbColReadStream::OpenLC(const RDbRowSet& aView,TDbColNo aCol)
+ {
+ OpenL(aView,aCol);
+ PushL();
+ }
+
+// Class RDbColWriteStream
+
+/** Opens the column with the specified ordinal in the current row, and in the
+specified rowset, and prepares the column for being written or replaced. The
+rowset must be updating or inserting a row.
+
+@param aView The rowset which has the row and column to be written.
+@param aCol The column ordinal of the column to be written.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbColWriteStream::OpenL(RDbRowSet& aView,TDbColNo aCol)
+ {
+ Attach(aView.ColSinkL(aCol));
+ }
+
+/** Opens the column with the specified ordinal in the current row, and in the
+specified rowset, and prepares the column for being written or replaced, putting
+a cleanup item for this object onto the cleanup stack. The rowset must be
+updating or inserting a row.
+
+Placing the cleanup object on the cleanup stack allows allocated resources
+to be cleaned up if a subsequent leave occurs.
+
+@param aView The rowset which has the row and column to be written.
+@param aCol The column ordinal of the column to be written.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the table.
+*/
+EXPORT_C void RDbColWriteStream::OpenLC(RDbRowSet& aView,TDbColNo aCol)
+ {
+ OpenL(aView,aCol);
+ PushL();
+ }
+
+// Class TDbWindow
+
+/** Constructs this object with the preferred shape. When fully evaluated, the
+view will try to have aForeSlots rows immediately available for navigation
+forwards, and aRearSlots rows immediately available for navigation backwards.
+
+@param aForeSlots The number of rows to evaluate ahead of the current row.
+@param aRearSlots The number of rows to evaluate behind the current row. */
+EXPORT_C TDbWindow::TDbWindow(TInt aForeSlots,TInt aRearSlots)
+ : iSize(aForeSlots+aRearSlots+1), iPreferredPos(aRearSlots)
+ {
+ __ASSERT_ALWAYS(aForeSlots>=0 && aRearSlots>=0,Panic(EDbInvalidViewWindowParameters));
+ }
+
+// Class RDbView
+
+/** Prepares the view object for evaluating an SQL select-statement.
+
+Following preparation, the rowset object can always provide schema information,
+but the view may first require evaluation to generate the rowset for navigation.
+
+@param aDatabase The database on which to execute the query.
+@param aQuery The SQL query and the text comparison mode for the constraint.
+@param anAccess The access specification for the rowset. By default, updatable
+access is given.
+@return KErrNone, if successful, otherwise one of the other system-wide error
+codes. Specifically: KErrNotFound if The table does not exist in the database
+or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification
+in the SQL query cannot be provided by an index.KErrArgument if an invalid
+or unrecognised SQL syntax was used.KErrGeneral if there is a column type
+mismatch in a predicate in the SQL query or if a date-literal in the SQL query
+was invalid.KErrOverflow if a number-literal in the SQL query for an integral
+column was too large (did not fit in a 32-bit integral representation). This
+can also be one of the DBMS database error codes..
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,TAccess anAccess)
+ {
+ return Prepare(aDatabase,aQuery,TDbWindow(),anAccess);
+ }
+
+/** Prepares the view object for evaluating an SQL select-statement and specifies
+the evaluation window shape for the rowset.
+
+The function does not specify the access specification for the rowset
+updatable access is given.
+
+Following preparation, the rowset object can always provide schema information,
+but the view may first require evaluation to generate the rowset for navigation.
+
+@param aDatabase The database on which to execute the query.
+@param aQuery The SQL query and the text comparison mode for the constraint.
+@param aWindow The desired evaluation window shape for the rowset. If this
+parameter is omitted, an alternative overload is called e.g. no pre-evaluation
+window is requested.
+@return KErrNone, if successful, otherwise one of the other system-wide error
+codes. Specifically: KErrNotFound if The table does not exist in the database
+or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification
+in the SQL query cannot be provided by an index.KErrArgument if an invalid
+or unrecognised SQL syntax was used.KErrGeneral if there is a column type
+mismatch in a predicate in the SQL query or if a date-literal in the SQL query
+was invalid.KErrOverflow if a number-literal in the SQL query for an integral
+column was too large (did not fit in a 32-bit integral representation). This
+can also be one of the DBMS database error codes.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,const TDbWindow& aWindow)
+ {
+ return Prepare(aDatabase,aQuery,aWindow,EUpdatable);
+ }
+
+/** Prepares the view object for evaluating an SQL select-statement, specifies
+the evaluation window shape for the rowset, and sets the access specification
+for the rowset.
+
+Following preparation, the rowset object can always provide schema information,
+but the view may first require evaluation to generate the rowset for navigation.
+
+@param aDatabase The database on which to execute the query.
+@param aQuery The SQL query and the text comparison mode for the constraint.
+@param aWindow The desired evaluation window shape for the rowset. If this
+parameter is omitted, an alternative overload is called e.g. no pre-evaluation
+window is requested.
+@param anAccess The access specification for the rowset. If omitted, updatable
+access is given.
+@return KErrNone, if successful, otherwise one of the other system-wide error
+codes. Specifically:KErrNotFound if The table does not exist in the database
+or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification
+in the SQL query cannot be provided by an index.KErrArgument if an invalid
+or unrecognised SQL syntax was used.KErrGeneral if there is a column type
+mismatch in a predicate in the SQL query or if a date-literal in the SQL query
+was invalid.KErrOverflow if a number-literal in the SQL query for an integral
+column was too large (did not fit in a 32-bit integral representation). This
+can also be one of the DBMS database error codes.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,const TDbWindow& aWindow,TAccess anAccess)
+ {
+ TRAPD(r,iCursor=aDatabase.iDatabase->ViewL(aQuery,aWindow,anAccess));
+ return r;
+ }
+
+/** Use this function to fully evaluate the view. It is equivalent to:
+
+while (Unevaluated()) { Evaluate(); }
+
+@return KErrNone, if successful, otherwise one of the system wide error codes. */
+EXPORT_C TInt RDbView::EvaluateAll()
+ {
+ TInt r;
+ do r=Evaluate(); while (r>0);
+ return r;
+ }
+
+/** Performs a single step of the view evaluation, and returns when the step is
+complete. To completely evaluate a view in one go, EvaluateAll() should be
+used.
+
+@return 0, evaluation is complete.> 0, more evaluation can be done. < 0, an
+error code, see the class overview for more information. */
+EXPORT_C TInt RDbView::Evaluate()
+ {
+ return iCursor->Evaluate();
+ }
+
+///** Performs a single step of the view evaluation, returning immediately and signalling
+//when the step is complete.
+//
+//This function is most effectively used when the view evaluation is carried
+//out from an active object.
+//
+//@param aStatus The request status used to contain completion information for
+//the function. On completion, the status value should be interpreted as follows:
+//0, evaluation is complete.> 0, more evaluation can be done. < 0, an error
+//code, see the class overview for more information. */
+//EXPORT_C void RDbView::Evaluate(TRequestStatus& aStatus)
+// {
+// iCursor->Evaluate(aStatus);
+// }
+
+/** Tests whether any more evaluation can be done to a view.
+
+@return ETrue, if the view can be further evaluated; EFalse, if evaluation will
+have no effect. */
+EXPORT_C TBool RDbView::Unevaluated() const
+ {
+ return iCursor->Unevaluated();
+ }
+
+// Class RDbTable
+
+/** Opens the named table object on a database with the specified access.
+
+If successful, the rowset is positioned to the beginning.
+
+@param aDatabase The database on which to open the table.
+@param aName The name of the table to open.
+@param anAccess The access specification for the rowset, the default is updatable
+access.
+@return KErrNone, if successful, otherwise one of the system-wide error codes.
+Specifically:KErrNotFound if the table does not exist in the database.KErrAccessDenied
+if an incremental operation is in progress. This can also be one of the DBMS
+database error codes.
+
+@capability Note For a secure shared database, the caller must satisfy either the read
+ or the write access policy for the table.
+*/
+EXPORT_C TInt RDbTable::Open(RDbDatabase &aDatabase,const TDesC &aName,TAccess anAccess)
+ {
+ TRAPD(r,iCursor=aDatabase.iDatabase->TableL(aName,anAccess));
+ return r;
+ }
+
+/** Sets the specified index as the active index for this table. The rows will
+be presented in index order, and this index key will be used for lookup by
+the SeekL() function.
+
+If successful, the rowset is reset to the beginning.
+
+@param anIndex The name of the index to activate.
+@return KErrNone, if successful, otherwise one of the system-wide error codes.
+Specifically:KErrWrite if the table was created with insert-only access.KErrNotFound
+if the index does not exist on the table. This can also be one of the DBMS
+database error codes.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TInt RDbTable::SetIndex(const TDesC* anIndex)
+ {
+ TRAPD(r,iCursor->SetIndexL(anIndex));
+ return r;
+ }
+
+/** Finds a row in a table based on a key in the active index.
+
+This function cannot be called while the rowset is currently updating or inserting
+a row. The currently active index on the table must have a key definition
+which matches the types in the key value.
+
+Less columns can be added to the key than are present in the index definition:
+the keys will only be compared up to the columns present further columns
+in the index are not considered.
+
+If successful the cursor is positioned to the row which was found, otherwise
+the cursor is left on an invalid row.
+
+The underlying Store database can leave with KErrWrite, if the table was created
+with insert-only access.
+
+The function can also leave with one of the DBMS database error codes.
+
+@param aKey The key value to lookup in the index.
+@param aComparison The comparison operation for the lookup, the default is
+to look for an exact match (EEqualTo).
+@return ETrue if a row which compares correctly with the key exists, EFalse if
+not.
+
+@capability Note For a secure shared database, the caller must satisfy the read
+ access policy for the table.
+*/
+EXPORT_C TBool RDbTable::SeekL(const TDbSeekKey& aKey,TComparison aComparison)
+ {
+ __ASSERT_ALWAYS(aKey.iKey.Count()>0,Panic(EDbNoColumnsInSeekKey));
+ return iCursor->SeekL(aKey.iKey,aComparison);
+ }
+
+// Class CDbCursor
+
+//
+// Default implementation in terms of ColumnDef. Might be inefficient
+//
+EXPORT_C void CDbCursor::ColumnsL(CDbColSet& aColSet)
+ {
+ TDbCol col;
+ TDbColNo max=ColumnCount();
+ for (TDbColNo ii=0;++ii<=max;)
+ {
+ ColumnDef(col,ii);
+ aColSet.AddL(col);
+ }
+ }
+
+//
+// Default implementation in terms of navigation
+// Faster counting may be possible
+//
+EXPORT_C TInt CDbCursor::CountL(RDbRowSet::TAccuracy)
+ {
+ TDbBookmark::TMark mark;
+ Bookmark(mark);
+ GotoL(RDbRowSet::EBeginning);
+ TInt count=0;
+ while (GotoL(RDbRowSet::ENext))
+ ++count;
+ GotoL(mark);
+ return count;
+ }
+
+//
+// Default implementation in terms of constraints
+//
+EXPORT_C TInt CDbCursor::FindL(RDbRowSet::TDirection aDirection,const TDbQuery& aCriteria)
+ {
+ CDbRowConstraint* constraint=ConstraintL(aCriteria);
+ constraint->PushL();
+ RDbRowSet::TPosition next=aDirection==RDbRowSet::EForwards ? RDbRowSet::ENext : RDbRowSet::EPrevious;
+ TInt skip=0;
+ do
+ {
+ if (MatchL(*constraint))
+ {
+ CleanupStack::PopAndDestroy(); // constraint
+ return skip;
+ }
+ ++skip;
+ } while (GotoL(next));
+ CleanupStack::PopAndDestroy();
+ return KErrNotFound;
+ }
+
+TInt CDbCursor::Evaluate()
+ {
+ TRAPD(r,r=EvaluateL());
+ return r;
+ }
+
+CDbRowConstraint* CDbCursor::ConstraintL(const TDbQuery& aQuery)
+ {
+ return AttachContext(this,OpenConstraintL(aQuery));
+ }
+
+//
+// Reserved for future development
+//
+EXPORT_C void CDbCursor::Reserved_1()
+ {
+ }
+
+//
+// Reserved for future development
+//
+EXPORT_C void CDbCursor::Reserved_2()
+ {
+ }