persistentstorage/dbms/utable/UT_CURS.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "UT_STD.H"
       
    17 
       
    18 // Class CDbTableCursor::HColumns
       
    19 
       
    20 class CDbTableCursor::HColumns
       
    21 	{
       
    22 public:
       
    23 	static HColumns* NewL(const CDbDataSource* aSource);
       
    24 	inline TInt Count() const
       
    25 		{return iCount;}
       
    26 	inline TDbColType Type(TDbColNo aCol) const
       
    27 		{__DEBUG(Check(aCol));return TDbColType(iType[aCol-1]);}
       
    28 	void Check(TDbColNo aCol) const;
       
    29 private:
       
    30 	TInt iCount;
       
    31 	TUint8 iType[1];
       
    32 	};
       
    33 
       
    34 CDbTableCursor::HColumns* CDbTableCursor::HColumns::NewL(const CDbDataSource* aSource)
       
    35 	{
       
    36 	TInt count=aSource->ColumnCount();
       
    37 	HColumns* self=(HColumns*)User::AllocL(_FOFF(HColumns,iType[count]));
       
    38 	self->iCount=count;
       
    39 	TUint8* pp=&self->iType[0];
       
    40 	for (TDbColNo ii=1;ii<=count;++ii,++pp)
       
    41 		*pp=aSource->ColumnDef(ii).iType;
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 void CDbTableCursor::HColumns::Check(TDbColNo aColNo) const
       
    46 	{
       
    47 	__ASSERT_ALWAYS(TUint(aColNo-1)<TUint(iCount),Panic(EDbInvalidColumn));
       
    48 	}
       
    49 
       
    50 // Class CDbTableCursor::CConstraint
       
    51 
       
    52 NONSHARABLE_CLASS(CDbTableCursor::CConstraint) : public CDbRowConstraint
       
    53 	{
       
    54 public:
       
    55 	CConstraint(CDbTableCursor& aCursor,CSqlSearchCondition* aSearchCondition,TDbTextComparison aComparison);
       
    56 	~CConstraint();
       
    57 //
       
    58 	inline TBool Check(CDbTableCursor& aCursor) const;
       
    59 	inline TBool MatchL() const;
       
    60 private:
       
    61 	CDbTableCursor& iCursor;
       
    62 	CSqlSearchCondition* iSearchCondition;
       
    63 	const TTextOps& iTextOps;
       
    64 	};
       
    65 
       
    66 CDbTableCursor::CConstraint::CConstraint(CDbTableCursor& aCursor,CSqlSearchCondition* aSearchCondition,TDbTextComparison aComparison)
       
    67 	: iCursor(aCursor), iSearchCondition(aSearchCondition), iTextOps(TTextOps::Ops(aComparison))
       
    68 	{}
       
    69 
       
    70 CDbTableCursor::CConstraint::~CConstraint()
       
    71 	{
       
    72 	delete iSearchCondition;
       
    73 	}
       
    74 
       
    75 inline TBool CDbTableCursor::CConstraint::Check(CDbTableCursor& aCursor) const
       
    76 	{return &iCursor==&aCursor;}
       
    77 inline TBool CDbTableCursor::CConstraint::MatchL() const
       
    78 	{return iSearchCondition->EvaluateL(iTextOps);}
       
    79 
       
    80 // Class CDbTableCursor
       
    81 
       
    82 inline void CDbTableCursor::CheckStateL() const
       
    83 	{iValid.CheckL();}
       
    84 inline RDbTransaction& CDbTableCursor::Transaction()
       
    85 	{__ASSERT(iValid);return iValid.Transaction();}
       
    86 inline TBool CDbTableCursor::InUpdate() const
       
    87 	{return iFlags&(EUpdating|EInserting);}
       
    88 
       
    89 CDbTableCursor::CDbTableCursor(RDbAccessPlan& aPlan,RDbRowSet::TAccess aAccess)
       
    90 	: iState(ERowBeginning),iValid(aPlan.Table()),iDataSource(aPlan.Adopt())
       
    91 	{
       
    92 	switch (aAccess)
       
    93 		{
       
    94 	default:
       
    95 		__ASSERT(0);
       
    96 	case RDbRowSet::EUpdatable:
       
    97 		iFlags=EUpdatable|EReadable;
       
    98 		break;
       
    99 	case RDbRowSet::EReadOnly:
       
   100 		iFlags=EReadable;
       
   101 		break;
       
   102 	case RDbRowSet::EInsertOnly:
       
   103 		iFlags=EUpdatable;
       
   104 		break;
       
   105 		}
       
   106 	}
       
   107 
       
   108 CDbTableCursor::~CDbTableCursor()
       
   109 	{
       
   110 	Cancel();
       
   111 	delete iDataSource;
       
   112 	delete iColumns;
       
   113 	}
       
   114 
       
   115 CDbTableCursor* CDbTableCursor::NewL(RDbAccessPlan& aPlan,RDbRowSet::TAccess aAccess)
       
   116 	{
       
   117 	CDbTableCursor* self=new(ELeave) CDbTableCursor(aPlan,aAccess);
       
   118 	CleanupStack::PushL(self);
       
   119 	self->iColumns=HColumns::NewL(self->iDataSource);
       
   120 	self->Reset();
       
   121 	CleanupStack::Pop();
       
   122 	return self;
       
   123 	}
       
   124 
       
   125 TDbColType CDbTableCursor::Type(TDbColNo aCol) const
       
   126 	{
       
   127 	iColumns->Check(aCol);
       
   128 	return iColumns->Type(aCol);
       
   129 	}
       
   130 
       
   131 void CDbTableCursor::Reset()
       
   132 //
       
   133 // Reset the cursor for re-evaluation
       
   134 //
       
   135 	{
       
   136 	AssertNotInUpdate();
       
   137 	if (iValid.Reset())
       
   138 		{
       
   139 		iDataSource->Reset();
       
   140 		iState=ERowBeginning;
       
   141 		}
       
   142 	}
       
   143 
       
   144 TBool CDbTableCursor::EvaluateL()
       
   145 //
       
   146 // Do a unit of evaluation work
       
   147 //
       
   148 	{
       
   149 	AssertNotInUpdate();
       
   150 	CheckStateL();
       
   151 	TInt work=256;
       
   152 	TBool atRow=EFalse;
       
   153 	TBool more=iDataSource->EvaluateL(work,iRecord,atRow);
       
   154 	if (atRow)
       
   155 		{	// evaluation results in a record appearing under the cursor
       
   156 		switch (iState)
       
   157 			{
       
   158 		case ERowEnd:
       
   159 		case ERowBeginning:
       
   160 			iState=ERowOK;
       
   161 			break;
       
   162 		case ERowDeletedAtEnd:
       
   163 			iState=ERowDeletedAtNext;
       
   164 			break;
       
   165 		default:
       
   166 			break;
       
   167 			}
       
   168 		}
       
   169 	return more?1:0;
       
   170 	}
       
   171 
       
   172 void CDbTableCursor::Evaluate(TRequestStatus& aStatus)
       
   173 //
       
   174 // Asynchronous evaluation: invoke synchronous version
       
   175 //
       
   176 	{
       
   177 	TRequestStatus* pStatus=&aStatus;
       
   178 	User::RequestComplete(pStatus,CDbCursor::Evaluate());
       
   179 	}
       
   180 
       
   181 TBool CDbTableCursor::Unevaluated()
       
   182 //
       
   183 // Report if there is evaluation to be done
       
   184 //
       
   185 	{
       
   186 	return iValid ? iDataSource->Unevaluated() : EFalse;
       
   187 	}
       
   188 
       
   189 TInt CDbTableCursor::CountL(RDbRowSet::TAccuracy aAccuracy)
       
   190 	{
       
   191 	AssertNotInUpdate();
       
   192 	CheckReadL();
       
   193 	TInt count=iDataSource->CountL();
       
   194 	return (count==KDbUndefinedCount && aAccuracy==RDbRowSet::EEnsure)
       
   195 		? CDbCursor::CountL(aAccuracy)
       
   196 		: count;
       
   197 	}
       
   198 
       
   199 TBool CDbTableCursor::AtBeginning()
       
   200 	{
       
   201 	return iState==ERowBeginning;
       
   202 	}
       
   203 
       
   204 TBool CDbTableCursor::AtEnd()
       
   205 	{
       
   206 	return iState==ERowEnd;
       
   207 	}
       
   208 
       
   209 TBool CDbTableCursor::AtRow()
       
   210 	{
       
   211 	return (iState==ERowOK||(iFlags&EInserting));
       
   212 	}
       
   213 
       
   214 TBool CDbTableCursor::GotoL(RDbRowSet::TPosition aPosition)
       
   215 //
       
   216 // Move the cursor in the requested direction
       
   217 // return whether we are at a row or not
       
   218 //
       
   219 	{
       
   220 	AssertNotInUpdate();
       
   221 	CheckReadL();
       
   222 	iFlags&=~ERead;
       
   223 	switch (aPosition)
       
   224 		{
       
   225 	default:
       
   226 		__ASSERT(0);
       
   227 	case RDbRowSet::EFirst:
       
   228 	case RDbRowSet::ELast:
       
   229 		break;
       
   230 	case RDbRowSet::ENext:
       
   231 		switch (iState)
       
   232 			{
       
   233 		default:
       
   234 			__ASSERT(0);
       
   235 		case ERowInLimbo:	// in between previous and next, must evaluate
       
   236 		case ERowOK:
       
   237 			break;
       
   238 		case ERowBeginning:		// goto first record
       
   239 			aPosition=RDbRowSet::EFirst;
       
   240 			break;
       
   241 		case ERowEnd:
       
   242 		case ERowInvalid:
       
   243 			Panic(EDbInvalidRow);
       
   244 			break;
       
   245 		case ERowDeletedAtNext:	// already have the id
       
   246 			if (iDataSource->GotoL(iRecord))
       
   247 				{	// and the record is still there
       
   248 				iState=ERowOK;
       
   249 				return ETrue;
       
   250 				}
       
   251 			break;
       
   252 		case ERowDeletedAtEnd:	// straight to end
       
   253 			iState=ERowEnd;
       
   254 			return EFalse;
       
   255 			}
       
   256 		break;
       
   257 	case RDbRowSet::EPrevious:
       
   258 		switch (iState)
       
   259 			{
       
   260 		default:
       
   261 			__ASSERT(0);
       
   262 		case ERowOK:
       
   263 		case ERowDeletedAtNext:		// goto previous will do what we want
       
   264 		case ERowInLimbo:	// in between previous and next, must evaluate
       
   265 			break;
       
   266 		case ERowEnd:				// goto last row
       
   267 		case ERowDeletedAtEnd:		// previous is last row
       
   268 			aPosition=RDbRowSet::ELast;
       
   269 			break;
       
   270 		case ERowBeginning:
       
   271 		case ERowInvalid:
       
   272 			Panic(EDbInvalidRow);
       
   273 			break;
       
   274 			}
       
   275 		break;
       
   276 	case RDbRowSet::EBeginning:
       
   277 		iState=ERowBeginning;
       
   278 		return EFalse;
       
   279 	case RDbRowSet::EEnd:
       
   280 		iState=ERowEnd;
       
   281 		return EFalse;
       
   282 		}
       
   283 	iState=ERowInvalid;
       
   284 	switch (iDataSource->GotoL(TDbPosition(aPosition),iRecord))
       
   285 		{
       
   286 	default:
       
   287 		__ASSERT(0);
       
   288 	case CDbDataSource::ESynchFailure:
       
   289 		__LEAVE(KErrNotReady);
       
   290 	case CDbDataSource::ESuccess:
       
   291 		iState=ERowOK;
       
   292 		return ETrue;
       
   293 	case CDbDataSource::ENoRow:
       
   294 		iState=TUint8(aPosition<RDbRowSet::EPrevious ? ERowEnd : ERowBeginning);
       
   295 		return EFalse;
       
   296 		}
       
   297 	}
       
   298 
       
   299 void CDbTableCursor::Bookmark(TDbBookmark::TMark& aMark)
       
   300 //
       
   301 // Create a bookmark for the current cursor state
       
   302 // Can bookmark ANY position.
       
   303 //
       
   304 	{
       
   305 	AssertNotInUpdate();
       
   306 	aMark.iMark[0]=iState;
       
   307 	aMark.iMark[1]=iRecord.Value();
       
   308 	}
       
   309 
       
   310 void CDbTableCursor::GotoL(const TDbBookmark::TMark& aMark)
       
   311 //
       
   312 // Reestablish the cursor state from a bookmark (if possible)
       
   313 //
       
   314 	{
       
   315 	AssertNotInUpdate();
       
   316 	CheckStateL();
       
   317 	iState=ERowInvalid;
       
   318 	iRecord=aMark.iMark[1];
       
   319 	TState state=TState(aMark.iMark[0]);
       
   320 	switch (state)
       
   321 		{
       
   322 	default:
       
   323 		Panic(EDbInvalidBookmark);
       
   324 	case ERowBeginning:
       
   325 	case ERowEnd:
       
   326 	case ERowDeletedAtEnd:
       
   327 	case ERowInLimbo:
       
   328 	case ERowInvalid:
       
   329 		break;
       
   330 	case ERowDeletedAtNext:
       
   331 	case ERowOK:
       
   332 		if (!iDataSource->GotoL(iRecord))
       
   333 			__LEAVE(KErrNotFound);
       
   334 		break;
       
   335 		}
       
   336 	iState=TUint8(state);
       
   337 	}
       
   338 
       
   339 void CDbTableCursor::GetL()
       
   340 //
       
   341 // read the current row into the row buffer for access
       
   342 //
       
   343 	{
       
   344 	AssertValidRow();
       
   345 	CheckStateL();
       
   346 	iFlags&=~ERead;
       
   347 	iDataSource->ReadRowL(iRecord);
       
   348 	iFlags|=ERead;
       
   349 	}
       
   350 
       
   351 void CDbTableCursor::InsertL(TInsert aClearRow)
       
   352 //
       
   353 // Insert a new row. If aCLearRow==aCopy, then copy the current row
       
   354 //
       
   355 	{
       
   356 	AssertNotInUpdate();
       
   357 	CheckUpdateL();
       
   358 	Transaction().DMLPrepareL(*this);
       
   359 	if (aClearRow==ECopy)
       
   360 		{
       
   361 		AssertValidRow();
       
   362 		iFlags&=~ERead;	// in case of failure in NewRowL
       
   363 		iDataSource->NewRowL(iRecord);
       
   364 		}
       
   365 	else
       
   366 		iDataSource->NewRowL(KDbNullRecordId);
       
   367 	iFlags|=EInserting|ERead;
       
   368 	Transaction().DMLBegin();
       
   369 	}
       
   370 
       
   371 void CDbTableCursor::UpdateL()
       
   372 	{
       
   373 	CheckUpdateL();
       
   374 	Transaction().DMLPrepareL(*this);
       
   375 	GetL();
       
   376 	iFlags|=EUpdating;
       
   377 	Transaction().DMLBegin();
       
   378 	}
       
   379 
       
   380 void CDbTableCursor::Cancel()
       
   381 	{
       
   382 	AssertNoStreams();
       
   383 	if (InUpdate())
       
   384 		{
       
   385 		RDbTransaction& t=Transaction();
       
   386 		if (iFlags&EDirty)
       
   387 			t.DMLTouch();			// we've mucked about with BLOBs, so force true roll-back
       
   388 		t.DMLRollback();
       
   389 		if (iFlags&EUpdating)
       
   390 			{
       
   391 			TRAP_IGNORE(iDataSource->ReadRowL(KDbNullRecordId));	// row buffer contains NULL row	(cannot fail)
       
   392 			}
       
   393 		iFlags&=(EUpdatable|EReadable);
       
   394 		}
       
   395 	}
       
   396 
       
   397 void CDbTableCursor::PutL()
       
   398 	{
       
   399 	AssertInUpdate();
       
   400 	CheckStateL();
       
   401 	CDbDataSource::TWrite mode=iFlags&EUpdating ? CDbDataSource::EReplace : CDbDataSource::EAppend;
       
   402 	iDataSource->PrepareToWriteRowL(mode);
       
   403 	RDbTransaction& t=Transaction();
       
   404 	t.DMLTouch();
       
   405 	iFlags&=~EDirty;
       
   406 	iRecord=iDataSource->WriteRowL(mode,iFlags&EReadable ? CDbDataSource::ESynch : CDbDataSource::ENoSynch);
       
   407 	t.DMLCommitL();
       
   408 	if ((iFlags&(EInserting|EReadable))==(EInserting|EReadable))
       
   409 		iState=ERowOK;
       
   410 	iFlags&=(EUpdatable|EReadable|ERead);
       
   411 	}
       
   412 
       
   413 void CDbTableCursor::DeleteL()
       
   414 	{
       
   415 	AssertValidRow();
       
   416 	CheckUpdateL();
       
   417 	RDbTransaction& t=Transaction();
       
   418 	t.DMLPrepareL(*this);
       
   419 	t.DMLBeginLC();
       
   420 	CDbDataSource::TDelete del=iDataSource->DeleteRowL(iRecord);
       
   421 	t.DMLCommitL();
       
   422 	CleanupStack::Pop();	// rollback not required
       
   423 	iState=TUint8(del+ERowDeletedAtNext);
       
   424 	}
       
   425 
       
   426 TInt CDbTableCursor::ColumnCount()
       
   427 	{
       
   428 	return iColumns->Count();
       
   429 	}
       
   430 
       
   431 void CDbTableCursor::ColumnDef(TDbCol& aCol,TDbColNo aColNo)
       
   432 	{
       
   433 	iColumns->Check(aColNo);
       
   434 	if (iValid)
       
   435 		iDataSource->ColumnDef(aColNo).AsTDbCol(aCol);
       
   436 	}
       
   437 
       
   438 TDbColType CDbTableCursor::ColumnType(TDbColNo aCol)
       
   439 	{
       
   440 	return Type(aCol);
       
   441 	}
       
   442 
       
   443 void CDbTableCursor::ReplaceBlobL(TDbColumn& aCol)
       
   444 	{
       
   445 	CheckStateL();
       
   446 	const TDbBlob& blob=TDbColumnC(aCol).Blob();
       
   447 	if (!blob.IsInline())
       
   448 		{
       
   449 		iFlags|=EDirty;
       
   450 		BlobsL().DeleteL(blob.Id());
       
   451 		}
       
   452 	}
       
   453 
       
   454 void CDbTableCursor::AddBlobSource()
       
   455 //
       
   456 // Increment the source count and take a read-lock on the database
       
   457 //
       
   458 	{
       
   459 	AddSource();
       
   460 	Transaction().ReadBegin(*this);
       
   461 	}
       
   462 
       
   463 void CDbTableCursor::ReleaseBlobSource()
       
   464 //
       
   465 // Decrement the source count and release the read-lock on the database
       
   466 //
       
   467 	{
       
   468 	ReleaseSource();
       
   469 	Transaction().ReadRelease(*this);
       
   470 	}
       
   471 
       
   472 MStreamBuf* CDbTableCursor::ColumnSourceL(TDbColNo aCol)
       
   473 	{
       
   474 	TDbColumnC col(ColumnC(aCol));
       
   475 	if ((iFlags&EWriteBuf) || iReadBuf==EMaxReadBuf)
       
   476 		__LEAVE(KErrInUse);			// only allow 1-write or 255-read streambufs
       
   477 	TDbColType type=iColumns->Type(aCol);
       
   478 	if (!TDbCol::IsLong(type))
       
   479 		return HMemBuf::NewL(*this,col.PtrC8());
       
   480 	// blobs
       
   481 	const TDbBlob& blob=col.Blob();
       
   482 	if (blob.IsInline())
       
   483 		return HMemBuf::NewL(*this,blob.PtrC8());
       
   484 	// if small enough, pull the blob data through immediately and avoid locking the database
       
   485 	if (blob.Size()<=HHeapBuf::EMaxBlobBuffer)
       
   486 		return HHeapBuf::NewL(*this,blob,type);
       
   487 	//
       
   488 	CheckStateL();
       
   489 	Transaction().ReadPrepareL(*this);
       
   490 	HReadBuf* buf=HReadBuf::NewLC(*this);
       
   491 	buf->Set(BlobsL().ReadL(blob.Id(),type));
       
   492 	CleanupStack::Pop();
       
   493 	return buf;
       
   494 	}
       
   495 
       
   496 MStreamBuf* CDbTableCursor::ColumnSinkL(TDbColNo aCol)
       
   497 	{
       
   498 	TDbColType type=Type(aCol);
       
   499 	__ASSERT_ALWAYS(TDbCol::IsLong(type),Panic(EDbWrongType));
       
   500 	TDbColumn col=Column(aCol);
       
   501 	ReplaceBlobL(col);
       
   502 	iFlags|=EDirty;
       
   503 	return HWriteBuf::NewL(*this,col,type);
       
   504 	}
       
   505 
       
   506 void CDbTableCursor::SetNullL(TDbColNo aCol)
       
   507 //
       
   508 // Make the column Null
       
   509 //
       
   510 	{
       
   511 	TDbColumn col=Column(aCol);
       
   512 	if (TDbCol::IsLong(Type(aCol)))
       
   513 		ReplaceBlobL(col);
       
   514 	col.SetNull();
       
   515 	}
       
   516 
       
   517 TInt CDbTableCursor::ColumnSize(TDbColNo aCol)
       
   518 	{
       
   519 	TDbColumnC col(ColumnC(aCol));
       
   520 	return TDbCol::IsLong(Type(aCol)) ? col.Blob().Size() : col.Size();
       
   521 	}
       
   522 
       
   523 RDbRow* CDbTableCursor::RowBuffer()
       
   524 //
       
   525 // Invoked by the server for whole-row access where possible
       
   526 //
       
   527 	{
       
   528 	__ASSERT(iFlags&ERead);
       
   529 	return iDataSource->RowBuffer();
       
   530 	}
       
   531 
       
   532 TDbColumnC CDbTableCursor::ColumnC(TDbColNo aCol)
       
   533 //
       
   534 // check row is valid for extraction
       
   535 //
       
   536 	{
       
   537 	__ASSERT_ALWAYS(iFlags&ERead,Panic(EDbRowNotRead));
       
   538 	return iDataSource->Column(aCol);
       
   539 	}
       
   540 
       
   541 TDbColumn CDbTableCursor::Column(TDbColNo aCol)
       
   542 //
       
   543 // check row is valid for writing
       
   544 //
       
   545 	{
       
   546 	AssertInUpdate();
       
   547 	return iDataSource->Column(aCol);
       
   548 	}
       
   549 
       
   550 void CDbTableCursor::SetIndexL(const TDesC* anIndex)
       
   551 	{
       
   552 	AssertNotInUpdate();
       
   553 	CheckReadL();
       
   554 	iDataSource->SetIndexL(anIndex);
       
   555 	iState=ERowBeginning;
       
   556 	}
       
   557 
       
   558 TBool CDbTableCursor::SeekL(const TDbLookupKey& aKey,RDbTable::TComparison aComparison)
       
   559 	{
       
   560 	AssertNotInUpdate();
       
   561 	CheckReadL();
       
   562 	iFlags&=~ERead;
       
   563 	iState=ERowInvalid;
       
   564 	TBool atrow=iDataSource->SeekL(aKey,aComparison,iRecord);
       
   565 	if (atrow)
       
   566 		iState=ERowOK;
       
   567 	return atrow;
       
   568 	}
       
   569 
       
   570 CDbRowConstraint* CDbTableCursor::OpenConstraintL(const TDbQuery& aCriteria)
       
   571 //
       
   572 // Construct a constraint for this rowset
       
   573 //
       
   574 	{
       
   575 	CSqlSearchCondition* sc=iDataSource->ParseConstraintLC(aCriteria.Query());
       
   576 	CDbRowConstraint* constraint=new(ELeave) CConstraint(*this,sc,aCriteria.Comparison());
       
   577 	CleanupStack::Pop();
       
   578 	return constraint;
       
   579 	}
       
   580 
       
   581 TBool CDbTableCursor::MatchL(CDbRowConstraint& aConstraint)
       
   582 	{
       
   583 	CConstraint& c=STATIC_CAST(CConstraint&,aConstraint);
       
   584 	__ASSERT_ALWAYS(c.Check(*this),Panic(EDbRowSetConstraintMismatch));
       
   585 	GetL();
       
   586 	return c.MatchL();
       
   587 	}
       
   588 
       
   589 void CDbTableCursor::CheckReadL() const
       
   590 //
       
   591 // Ensure we are a readable cursor
       
   592 //
       
   593 	{
       
   594 	CheckStateL();
       
   595 	if ((iFlags&EReadable)==0)
       
   596 		__LEAVE(KErrWrite);
       
   597 	}
       
   598 
       
   599 void CDbTableCursor::CheckUpdateL() const
       
   600 //
       
   601 // Ensure we are a writable cursor
       
   602 //
       
   603 	{
       
   604 	CheckStateL();
       
   605 	if ((iFlags&EUpdatable)==0)
       
   606 		__LEAVE(KErrWrite);
       
   607 	}
       
   608 
       
   609 void CDbTableCursor::AssertNoStreams() const
       
   610 	{
       
   611 	__ASSERT_ALWAYS((iFlags&EWriteBuf)==0 && iReadBuf==0,Panic(EDbStreamOpen));
       
   612 	}
       
   613 
       
   614 void CDbTableCursor::AssertNotInUpdate() const
       
   615 	{
       
   616 	__ASSERT_ALWAYS(!InUpdate(),Panic(EDbInUpdate));
       
   617 	AssertNoStreams();
       
   618 	}
       
   619 
       
   620 void CDbTableCursor::AssertInUpdate() const
       
   621 	{
       
   622 	__ASSERT_ALWAYS(InUpdate(),Panic(EDbNotInUpdate));
       
   623 	AssertNoStreams();
       
   624 	}
       
   625 
       
   626 void CDbTableCursor::AssertValidRow() const
       
   627 	{
       
   628 	AssertNotInUpdate();
       
   629 	__ASSERT_ALWAYS(iState==ERowOK||(iFlags&EInserting),Panic(EDbInvalidRow));
       
   630 	}
       
   631