os/persistentdata/persistentstorage/dbms/udbms/UD_CURS.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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 "UD_STD.H"
    17 
    18 // Class RDbRowSet
    19 
    20 /** Resets the rowset.
    21 
    22 For a Table, this just sets the rowset cursor to the beginning position.
    23 
    24 For an SQL view, this discards any evaluated rows and returns the cursor to 
    25 the beginning. The view then requires reevaluation.
    26 
    27 The Store Database implementation requires this function to be called in order 
    28 to recover an open rowset object after the database has been rolled back. 
    29 The rowset does not need to be closed in this situation.
    30 
    31 If a rowset object requires a reset, then all row functions return or leave 
    32 with KErrNotReady. */
    33 EXPORT_C void RDbRowSet::Reset()
    34 	{
    35 	iCursor->Reset();
    36 	}
    37 
    38 /** Closes the rowset and releases any owned resources. It is safe to close a rowset 
    39 object which is not open. */
    40 EXPORT_C void RDbRowSet::Close()
    41 	{
    42 	iCursor.Close();
    43 	}
    44 
    45 /** Returns the number of rows available in a rowset.
    46 	
    47 This can take some time to complete, and a parameter can be passed to request 
    48 a quick but not always thorough count of the rows.
    49 
    50 For SQL views, the value returned depends on the evaluation window being used 
    51 by the view. If there is an evaluation window this function will always return 
    52 the number of rows available in the window, not the total number which could 
    53 be returned by the query.
    54 
    55 @param anAccuracy This specifies whether to ensure that an accurate count 
    56 is returned, or to give up if this value is not readily available. The default 
    57 is to ensure an accurate count.
    58 @return The number of rows available in the rowset, or KDbUndefinedCount if 
    59 EQuick was specified and the count was not available. 
    60 
    61 @capability Note For a secure shared database, the caller must satisfy either the read
    62             or the write access policy for the table.
    63 */
    64 EXPORT_C TInt RDbRowSet::CountL(TAccuracy aAccuracy) const
    65 	{
    66 	return iCursor->CountL(aAccuracy);
    67 	}
    68 
    69 /** Tests whether there are any rows in the rowset. This is often faster than testing 
    70 whether CountL()==0.
    71 
    72 @return ETrue if there are no rows available in the rowset, EFalse if there 
    73 are one or more. 
    74 
    75 @capability Note For a secure shared database, the caller must satisfy the read
    76             access policy for the table.
    77 */
    78 EXPORT_C TBool RDbRowSet::IsEmptyL() const
    79 	{
    80 	if (AtRow())
    81 		return EFalse;
    82 	TInt count=CountL(EQuick);
    83 	if (count!=KDbUndefinedCount)
    84 		return count==0;
    85 	TDbBookmark mark=Bookmark();
    86 	CDbCursor& cursor=*iCursor;
    87 	TBool hasRow=cursor.GotoL(EFirst);
    88 	cursor.GotoL(mark.iMark);
    89 	return !hasRow;
    90 	}
    91 
    92 /** Returns the entire column set for the rowset. This can be used to discover 
    93 column ordinals for named columns in this rowset.
    94 
    95 The function leaves with KErrNoMemory if there is not enough memory to carry 
    96 out the operation. 
    97 
    98 @return The column set object which describes this rowset structure. The caller 
    99 should delete it when it is no longer required. */
   100 EXPORT_C CDbColSet* RDbRowSet::ColSetL() const
   101 	{
   102 	CDbColSet* cs=CDbColSet::NewLC();
   103 	iCursor->ColumnsL(*cs);
   104 	CleanupStack::Pop();
   105 	return cs;
   106 	}
   107 
   108 /** Returns the number of columns which are defined in this rowset.
   109 
   110 @return The number of columns which are defined in this rowset. */
   111 EXPORT_C TInt RDbRowSet::ColCount() const
   112 	{
   113 	return iCursor->ColumnCount();
   114 	}
   115 
   116 /** Returns the type of a column in the rowset.
   117 	
   118 @param aCol The column ordinal for which the column type is required. Column 
   119 ordinals range from 1 to ColCount().
   120 @return The type of the column aCol. */
   121 EXPORT_C TDbColType RDbRowSet::ColType(TDbColNo aColNo) const
   122 	{
   123 	return iCursor->ColumnType(aColNo);
   124 	}
   125 
   126 /** Returns the definition of a column in the rowset.
   127 	
   128 @param aCol The column ordinal for which the column definition is required. 
   129 Column ordinals range from 1 to ColCount().
   130 @return The definition of the column aCol. */
   131 EXPORT_C TDbCol RDbRowSet::ColDef(TDbColNo aColNo) const
   132 	{
   133 	TDbCol col;
   134 	iCursor->ColumnDef(col,aColNo);
   135 	return col;
   136 	}
   137 
   138 /** Tests whether the cursor is on a row.
   139 
   140 One of the following is true:
   141 
   142 the rowset is currently updating a row
   143 
   144 the rowset is currently inserting a row
   145 
   146 GetL() can be called to retrieve the row
   147 
   148 @return ETrue if the cursor is on a valid row; EFalse, otherwise. */
   149 EXPORT_C TBool RDbRowSet::AtRow() const
   150 	{
   151 	return iCursor->AtRow();
   152 	}
   153 
   154 /** Tests whether the cursor is at the beginning of the rowset.
   155 
   156 @return ETrue if the cursor is at the beginning, otherwise EFalse. */
   157 EXPORT_C TBool RDbRowSet::AtBeginning() const
   158 	{
   159 	return iCursor->AtBeginning();
   160 	}
   161 
   162 /** Tests whether the cursor is at the end of the rowset.
   163 
   164 @return ETrue if the cursor is at the end, otherwise EFalse. */
   165 EXPORT_C TBool RDbRowSet::AtEnd() const
   166 	{
   167 	return iCursor->AtEnd();
   168 	}
   169 
   170 /** Moves the cursor to a specified position.
   171 
   172 This is invoked by Beginning(), End(), FirstL(), LastL(), NextL() and PreviousL() 
   173 to navigate the cursor. See those functions for descriptions of how the cursor 
   174 behaves given different position specifications.
   175 
   176 @param aPosition Specifies the position to move the cursor to.
   177 @return ETrue if the cursor is now at a row, EFalse if it is at the beginning 
   178 or end. 
   179 
   180 @capability Note For a secure shared database, the caller must satisfy the read
   181             access policy for the table.
   182 */
   183 EXPORT_C TBool RDbRowSet::GotoL(TPosition aPosition)
   184 	{
   185 	return iCursor->GotoL(aPosition);
   186 	}
   187 
   188 /** Gets the bookmark for the current cursor position. Bookmarks cannot be extracted 
   189 when the rowset is updating or inserting a row.
   190 
   191 The Store Database implementation allows bookmarks to be extracted for any 
   192 cursor position including the beginning and end.
   193 
   194 @return A bookmark which can be used to return to the current position using 
   195 the GotoL() function. 
   196 
   197 @capability Note For a secure shared database, the caller must satisfy the read
   198             access policy for the table.
   199 */
   200 EXPORT_C TDbBookmark RDbRowSet::Bookmark() const
   201 	{
   202 	TDbBookmark mark;
   203 	iCursor->Bookmark(mark.iMark);
   204 	return mark;
   205 	}
   206 
   207 /** Goes to a previously bookmarked position in a rowset.
   208 
   209 The Store Database implements bookmarks which are valid in any rowset based 
   210 on the same table or generated by the same query, and which persist across 
   211 transaction boundaries.
   212 
   213 @param aMark The bookmark to return to. This should have been returned by 
   214 a previous call to Bookmark() on this or an equivalent rowset object. 
   215 
   216 @capability Note For a secure shared database, the caller must satisfy the read
   217             access policy for the table.
   218 */
   219 EXPORT_C void RDbRowSet::GotoL(const TDbBookmark& aMark)
   220 	{
   221 	iCursor->GotoL(aMark.iMark);
   222 	}
   223 
   224 /** Gets the current row data for access using the column extractor functions. 
   225 The cursor must be positioned at a valid row. 
   226 
   227 @capability Note For a secure shared database, the caller must satisfy the read
   228             access policy for the table.
   229 */
   230 EXPORT_C void RDbRowSet::GetL()
   231 	{
   232 	iCursor->GetL();
   233 	}
   234 
   235 /** Inserts a new row into the rowset. All auto-increment columns will be initialised 
   236 with their new values, all other columns will be initialised to NULL values. 
   237 If no client-begun transaction is in progress, this function begins an automatic 
   238 transaction, which is committed by PutL().
   239 
   240 After the column values have been set using the SetColL() functions, the row 
   241 can be written to the database using PutL(). 
   242 
   243 @capability Note For a secure shared database, the caller must satisfy the write
   244             access policy for the table.
   245 */
   246 EXPORT_C void RDbRowSet::InsertL()
   247 	{
   248 	iCursor->InsertL(CDbCursor::EClear);
   249 	}
   250 
   251 /** Inserts a copy of the current row into the rowset. All auto-increment columns 
   252 will be given a new value (as for InsertL()), the other columns will copy 
   253 their values from the cursor's current row. If no client-begun transaction 
   254 is in progress, this function begins an automatic transaction, which is committed 
   255 by PutL().
   256 
   257 After the column values have been modified using the SetColL() functions, 
   258 the row can be written to the database using PutL(). 
   259 
   260 @capability Note For a secure shared database, the caller must satisfy the write
   261             access policy for the table.
   262 */
   263 EXPORT_C void RDbRowSet::InsertCopyL()
   264 	{
   265 	iCursor->InsertL(CDbCursor::ECopy);
   266 	}
   267 
   268 /** Prepares the current row for update. If no client-begun transaction is in progress, 
   269 this function begins an automatic transaction, which is committed by PutL().
   270 
   271 After the column values have been modified using the SetColL() functions, 
   272 the row can be written back to the database using PutL(). 
   273 
   274 @capability Note For a secure shared database, the caller must satisfy the write
   275             access policy for the table.
   276 */
   277 EXPORT_C void RDbRowSet::UpdateL()
   278 	{
   279 	iCursor->UpdateL();
   280 	}
   281 
   282 /** Completes the update or insertion of a row.
   283 
   284 First the new row data is validated:
   285 
   286 not-null columns are checked to be not NULL
   287 
   288 numerical columns are checked to be in range for their type
   289 
   290 variable length columns are checked to not exceed their maximum length
   291 
   292 unique index keys are checked to ensure uniqueness is not violated
   293 
   294 Note that modifying auto-increment columns is not prevented by DBMS.
   295 
   296 Following validation the data is written to the database and any affected 
   297 indexes are updated. On successful completion of the write, PutL() will then 
   298 commit any automatic transaction.
   299 
   300 The cursor is left positioned on the updated or inserted row — where this 
   301 lies in the rowset is not always well defined. To return to the row which 
   302 was current prior to the update or insertion, a bookmark can be used.
   303 
   304 In the Store Database implementation the written row is located in the rowset 
   305 as follows:
   306 
   307 Tables without an active index will leave updated rows in the same location 
   308 and append new rows to the end of the rowset.
   309 
   310 Tables with an active index place the row according to the active index ordering.
   311 
   312 SQL views without an evaluation window will place it according to the rowset 
   313 ordering. The row may subsequently disappear if it does not match the WHERE 
   314 clause of the SQL query.
   315 
   316 SQL views with a full evaluation window will leave updated rows in the same 
   317 location and append new rows to the end of the rowset. Re-evaluation may cause 
   318 the row to disappear if it does not match the WHERE clause of the SQL query.
   319 
   320 SQL views with a partial evaluation window will leave updated rows in the 
   321 same location, new rows are not added to the window and navigation from the 
   322 new row is undefined. Further navigation and evaluation of the partial window 
   323 will place the rows in the correct location according to the query. 
   324 
   325 @capability Note For a secure shared database, the caller must satisfy the write
   326             access policy for the table.
   327 */
   328 EXPORT_C void RDbRowSet::PutL()
   329 	{
   330 	iCursor->PutL();
   331 	}
   332 
   333 /** Deletes the current row in a rowset. The rowset must not currently be updating 
   334 or inserting the row.
   335 
   336 The rowset cursor is left positioned at the "hole" left by the deletion of 
   337 the current row. Navigation to the next or previous row will have the same 
   338 effect as if this row had not been deleted. Once the cursor has been moved 
   339 from the "hole" it will disappear from the rowset.
   340 
   341 If the client has not begun a transaction, this function will use an automatic 
   342 transaction to update the rowset. 
   343 
   344 @capability Note For a secure shared database, the caller must satisfy the write
   345             access policy for the table.
   346 */
   347 EXPORT_C void RDbRowSet::DeleteL()
   348 	{
   349 	iCursor->DeleteL();
   350 	}
   351 
   352 /** Cancels the update or insertion of a row, or recovers the rowset if PutL() 
   353 fails. The cursor will return to the location prior to starting the update 
   354 or insertion. It is also safe to call this function when the rowset object 
   355 is not updating or inserting a row, in which case it does nothing.
   356 
   357 In the Store database implementation, if this is called to abort a row update 
   358 or insertion before PutL() is called or during row validation in PutL(), all 
   359 the changes are discarded without requiring a transaction rollback and the 
   360 rowset to be Reset(). */
   361 EXPORT_C void RDbRowSet::Cancel()
   362 	{
   363 	iCursor->Cancel();
   364 	}
   365 
   366 //
   367 // Checks for valid Cursor and column ID
   368 //
   369 CDbCursor& RDbRowSet::CheckCol(TDbColNo aCol) const
   370 	{
   371 	CDbCursor& cr=*iCursor;
   372 	__ASSERT_ALWAYS(aCol>0&&aCol<=cr.ColumnCount(),Panic(EDbInvalidColumn));
   373 	return cr;
   374 	}
   375 
   376 //
   377 // Checks for valid Cursor, column ID and type
   378 //
   379 TDbColumnC RDbRowSet::ColumnC(TDbColNo aCol,TDbColType aType) const
   380 	{
   381 	CDbCursor& cr=*iCursor;
   382 	TDbColType cType=cr.ColumnType(aCol);
   383 	if (cType!=aType)
   384 		{	// not an exact match
   385 		if (cType>aType)
   386 			Panic(EDbWrongType);		// extraction type is narrower
   387 		else if (!IsIntegral(cType))
   388 			Panic(EDbWrongType);		// type is non-integral
   389 		else if (IsSigned(cType) && IsUnsigned(aType))
   390 			Panic(EDbWrongType);		// cannot get signed column as unsigned
   391 		}
   392 	return cr.ColumnC(aCol);
   393 	}
   394 
   395 TDbColumn RDbRowSet::Column(TDbColNo aCol,TDbColType aType)
   396 	{
   397 	CDbCursor& cr=*iCursor;
   398 	__ASSERT_ALWAYS(cr.ColumnType(aCol)==aType,Panic(EDbWrongType));
   399 	return cr.Column(aCol);
   400 	}
   401 
   402 /** Gets the size in bytes of a column value. This can be used for all column types, 
   403 including Long columns. NULL columns return a size of 0.
   404 
   405 Note:
   406 
   407 This may yield unexpected results for small numerical column types as they 
   408 are stored in memory as 32-bit values.
   409 
   410 @param aCol The column ordinal of the column to check.
   411 @return The length in bytes of column aCol's value. */
   412 EXPORT_C TInt RDbRowSet::ColSize(TDbColNo aCol) const
   413 	{
   414 	return iCursor->ColumnSize(aCol);
   415 	}
   416 
   417 /** Gets the length of a column value. As compared with ColSize(), this returns 
   418 the number of "units" in the column:
   419 
   420 NULL columns have a length of 0
   421 
   422 non-NULL numerical and date-time columns have a length of 1
   423 
   424 for Text columns the length is the character count
   425 
   426 for Binary columns the length is the byte count
   427 
   428 @param aCol The column ordinal of the column to check.
   429 @return The length in "units" of column aCol's value. */
   430 EXPORT_C TInt RDbRowSet::ColLength(TDbColNo aCol) const
   431 	{
   432 	TInt size=ColSize(aCol);
   433 	switch (iCursor()->ColumnType(aCol))
   434 		{
   435 	case EDbColText8:
   436 	case EDbColLongText8:
   437 	case EDbColBinary:
   438 	case EDbColLongBinary:
   439 		break;
   440 	case EDbColText16:
   441 	case EDbColLongText16:
   442 		if (size>0)
   443 			size>>=1;
   444 		break;
   445 	default:
   446 		if (size)
   447 			size=1;
   448 		break;
   449 		}
   450 	return size;
   451 	}
   452 
   453 /** Extracts a TInt8 column value.
   454 
   455 @param aCol The column ordinal of the column to extract.
   456 @return The value of column aCol. */
   457 EXPORT_C TInt8 RDbRowSet::ColInt8(TDbColNo aCol) const
   458 	{
   459 	return ColumnC(aCol,EDbColInt8).Int8();
   460 	} 
   461 
   462 /** Extracts a TInt16 or TInt8 column value.
   463 
   464 @param aCol The column ordinal of the column to extract.
   465 @return The value of column aCol. */
   466 EXPORT_C TInt16 RDbRowSet::ColInt16(TDbColNo aCol) const
   467 	{
   468 	return ColumnC(aCol,EDbColInt16).Int16();
   469 	} 
   470 
   471 /** Extracts a TInt32, TInt16 or TInt8 column value.
   472 
   473 @param aCol The column ordinal of the column to extract.
   474 @return The value of column aCol. */
   475 EXPORT_C TInt32 RDbRowSet::ColInt32(TDbColNo aCol) const
   476 	{
   477 	return ColumnC(aCol,EDbColInt32).Int32();
   478 	} 
   479 
   480 /** Extracts a TInt64 column value.
   481 
   482 @param aCol The column ordinal of the column to extract.
   483 @return The value of column aCol. */
   484 EXPORT_C TInt64 RDbRowSet::ColInt64(TDbColNo aCol) const
   485 	{
   486 	CDbCursor& cr=*iCursor;
   487 	TDbColumnC c=cr.ColumnC(aCol);
   488 	TDbColType t=cr.ColumnType(aCol);
   489 	if (t==EDbColInt64)
   490 		return c.Int64();
   491 	if (t>EDbColInt64)
   492 		Panic(EDbWrongType);
   493 	if (IsSigned(t))
   494 		return TInt(c.Int32());
   495 	return TUint(c.Uint32());
   496 	} 
   497 
   498 /** Extracts a Uint8 or Bit column value.
   499 
   500 @param aCol The column ordinal of the column to extract.
   501 @return The value of column aCol. */
   502 EXPORT_C TUint8 RDbRowSet::ColUint8(TDbColNo aCol) const
   503 	{
   504 	return ColumnC(aCol,EDbColUint8).Uint8();
   505 	} 
   506 
   507 /** Extracts a Uint16, Uint8 or Bit column value.
   508 
   509 @param aCol The column ordinal of the column to extract.
   510 @return The value of column aCol. */
   511 EXPORT_C TUint16 RDbRowSet::ColUint16(TDbColNo aCol) const
   512 	{
   513 	return ColumnC(aCol,EDbColUint16).Uint16();
   514 	} 
   515 
   516 /** Extracts a Uint32, Uint16, Uint8 or Bit column value.
   517 
   518 @param aCol The column ordinal of the column to extract.
   519 @return The value of column aCol. */
   520 EXPORT_C TUint32 RDbRowSet::ColUint32(TDbColNo aCol) const
   521 	{
   522 	return ColumnC(aCol,EDbColUint32).Uint32();
   523 	} 
   524 
   525 /** Extracts a TReal32 column value.
   526 
   527 @param aCol The column ordinal of the column to extract.
   528 @return The value of column aCol. */
   529 EXPORT_C TReal32 RDbRowSet::ColReal32(TDbColNo aCol) const __SOFTFP
   530 	{
   531 	return ColumnC(aCol,EDbColReal32).Real32();
   532 	} 
   533 
   534 /** Extracts a TReal64 column value.
   535 
   536 @param aCol The column ordinal of the column to extract.
   537 @return The value of column aCol. */
   538 EXPORT_C TReal64 RDbRowSet::ColReal64(TDbColNo aCol) const __SOFTFP
   539 	{
   540 	return ColumnC(aCol,EDbColReal64).Real64();
   541 	} 
   542 
   543 /** Extracts a TTime column value.
   544 
   545 @param aCol The column ordinal of the column to extract.
   546 @return The value of column aCol. TTime may be either local time or universal time. 
   547 DBMS doesn't interpret the value of TTime, it is left up to the user to know which has been used.*/
   548 EXPORT_C TTime RDbRowSet::ColTime(TDbColNo aCol) const
   549 	{
   550 	return ColumnC(aCol,EDbColDateTime).Time();
   551 	} 
   552 
   553 /** Extracts any column type, except Long columns, as binary data.
   554 Can handle any type of non-long column
   555 
   556 @param aCol The column ordinal of the column to extract.
   557 @return A descriptor of column aCol's value. */
   558 EXPORT_C TPtrC8 RDbRowSet::ColDes8(TDbColNo aCol) const
   559 	{
   560 	CDbCursor& cr=*iCursor;
   561 	__ASSERT_ALWAYS(!IsLong(cr.ColumnType(aCol)),Panic(EDbWrongType));
   562 	return cr.ColumnC(aCol).PtrC8();
   563 	} 
   564 
   565 /** Extracts a column as Unicode text.
   566 
   567 @param aCol The column ordinal of the column to extract
   568 @return A descriptor of column aCol's value. */
   569 EXPORT_C TPtrC16 RDbRowSet::ColDes16(TDbColNo aCol) const
   570 	{
   571 	return ColumnC(aCol,EDbColText16).PtrC16();
   572 	}
   573 
   574 /** Extracts a Text column value. The column type must match the default descriptor 
   575 type to use this extractor, ie. it must be equal to EDbColText.
   576 
   577 @param aCol The column ordinal of the column to extract.
   578 @return A descriptor of column aCol's value. */
   579 EXPORT_C TPtrC RDbRowSet::ColDes(TDbColNo aCol) const
   580 	{
   581 	return ColDes16(aCol);
   582 	}
   583 
   584 /** Use this function to set the value of a column to NULL.
   585 
   586 @param aCol The column ordinal of the column to set to NULL. 
   587 
   588 @capability Note For a secure shared database, the caller must satisfy the write
   589             access policy for the table.
   590 */
   591 EXPORT_C void RDbRowSet::SetColNullL(TDbColNo aCol)
   592 	{
   593 	iCursor->SetNullL(aCol);
   594 	}
   595 
   596 /** Sets a TInt32, TInt16 or TInt8 column value.
   597 
   598 @param aCol The column ordinal of the column to set.
   599 @param aValue The new column value. */
   600 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TInt32 aValue)
   601 	{
   602 	CDbCursor& cr=*iCursor;
   603 	TDbColType t=cr.ColumnType(aCol);
   604 	if (t<EDbColInt64)
   605 		{	// set any <= 32-bit integral type
   606 		if (IsSigned(t))
   607 			{
   608 			cr.Column(aCol).SetL(aValue);
   609 			return;
   610 			}
   611 		if (aValue>=0)
   612 			{	// check the domain for unsigned columns
   613 			cr.Column(aCol).SetL(aValue);
   614 			return;
   615 			}
   616 		}
   617 	Panic(EDbWrongType);
   618 	}
   619 
   620 /** Sets a TInt64 column value.
   621 
   622 @param aCol The column ordinal of the column to set.
   623 @param aValue The new column value. */
   624 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TInt64 aValue)
   625 	{
   626 	CDbCursor& cr=*iCursor;
   627 	TDbColumn c=cr.Column(aCol);
   628 	TDbColType t=cr.ColumnType(aCol);
   629 	if (t==EDbColInt64)
   630 		{		// exact match
   631 		c.SetL(aValue);
   632 		return;
   633 		}
   634 	if (t<EDbColInt64)
   635 		{
   636 		TInt32 l = I64LOW(aValue);
   637 		TInt32 h = I64HIGH(aValue);
   638 		if (IsSigned(t))
   639 			{	// check the domain for signed 32-bit 
   640 			if (h==l>>31)		// sign-extend l gives aValue
   641 				{
   642 				c.SetL(l);
   643 				return;
   644 				}
   645 			}	// invalid type, drop through to panic
   646 		else
   647 			{	// check the domain for unsigned 32-bit 
   648 			if (h==0)
   649 				{				// zero extend l gives aValue
   650 				c.SetL(l);	// in unsigned 32 bit range
   651 				return;
   652 				}
   653 			}	// invalid type, drop through to panic
   654 		}
   655 	Panic(EDbWrongType);
   656 	}
   657 
   658 /** Sets a TUint32, TUint16, TUint8 or Bit column value.
   659 
   660 @param aCol The column ordinal of the column to set.
   661 @param aValue The new column value. */
   662 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TUint32 aValue)
   663 	{
   664 	CDbCursor& cr=*iCursor;
   665 	TDbColType t=cr.ColumnType(aCol);
   666 	if (t<EDbColInt64)
   667 		{	// set any <= 32-bit integral type
   668 		if (IsUnsigned(t))
   669 			{
   670 			cr.Column(aCol).SetL(aValue);
   671 			return;
   672 			}
   673 		if (aValue<=TUint32(KMaxTInt))
   674 			{	// check the domain for signed columns
   675 			cr.Column(aCol).SetL(aValue);
   676 			return;
   677 			}
   678 		}
   679 	Panic(EDbWrongType);
   680 	}
   681 
   682 /** Sets a TReal32 column value.
   683 
   684 @param aCol The column ordinal of the column to set.
   685 @param aValue The new column value. */
   686 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TReal32 aValue) __SOFTFP
   687 	{
   688 	Column(aCol,EDbColReal32).SetL(aValue);
   689 	}
   690 
   691 /** Sets a TReal64 column value.
   692 
   693 @param aCol The column ordinal of the column to set.
   694 @param aValue The new column value. */
   695 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TReal64 aValue) __SOFTFP
   696 	{
   697 	Column(aCol,EDbColReal64).SetL(aValue);
   698 	}
   699 
   700 /** Sets a TTime column value.
   701 
   702 TTime could be either local time or universal time. 
   703 DBMS doesn't interpret the value of TTime, it is left up to the user to decide which should be used.
   704 
   705 @param aCol The column ordinal of the column to set.
   706 @param aValue The new column value. */
   707 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,TTime aValue)
   708 	{
   709 	Column(aCol,EDbColDateTime).SetL(aValue);
   710 	}
   711 
   712 /** Sets a column value from an 8 bit descriptor. This function can also set the 
   713 value of Long columns.
   714 
   715 Usually this is used to set a Text8 or LongText8 column from a non-Unicode 
   716 text descriptor, but can be used for any column type: the data content is 
   717 validated when the row is PutL().
   718 
   719 @param aCol The column ordinal of the column to set.
   720 @param aValue The new column value. */
   721 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,const TDesC8 &aValue)
   722 	{
   723 	CDbCursor& c=*iCursor;
   724 	if (IsLong(c.ColumnType(aCol)))
   725 		{
   726 		RDbColWriteStream strm;
   727 		strm.OpenLC(*this,aCol);
   728 		strm.WriteL(aValue);
   729 		strm.CommitL();
   730 		CleanupStack::PopAndDestroy();
   731 		}
   732 	else
   733 		c.Column(aCol).SetL(aValue);
   734 	}
   735 
   736 /** Set a column value from Unicode text.
   737 
   738 @param aCol The column ordinal of the column to set.
   739 @param aValue The new column value. */
   740 EXPORT_C void RDbRowSet::SetColL(TDbColNo aCol,const TDesC16 &aValue)
   741 	{
   742 	CDbCursor& c=*iCursor;
   743 	if (c.ColumnType(aCol)==EDbColLongText16)
   744 		{
   745 		RDbColWriteStream strm;
   746 		strm.OpenLC(*this,aCol);
   747 		strm.WriteL(aValue);
   748 		strm.CommitL();
   749 		CleanupStack::PopAndDestroy();
   750 		}
   751 	else
   752 		Column(aCol,EDbColText16).SetL(aValue);
   753 	}
   754 
   755 /** Searches through a rowset for a row which fulfils an SQL search-condition. 
   756 The search begins from the current position (which must be a valid row) and 
   757 proceeds forwards or backwards through the available rows until it finds a 
   758 match or runs out of rows.
   759 
   760 The cursor is positioned to the matching row (or beginning/end of set) on 
   761 return.
   762 
   763 This is a brute-force approach to finding a row using an index for key-based 
   764 retrieval on a Table rowset is a much faster but less flexible way of finding 
   765 rows.
   766 
   767 @param aDirection Specifies which direction to search after testing the current 
   768 row.
   769 @param aCriteria A query object containing an SQL search-condition to match 
   770 against.
   771 @return If no match is found KErrNotFound is returned. Otherwise the number 
   772 of rows navigated while finding a match, which may be 0 if the current row 
   773 matches. 
   774 
   775 @capability Note For a secure shared database, the caller must satisfy the read
   776             access policy for the table.
   777 */
   778 EXPORT_C TInt RDbRowSet::FindL(TDirection aDirection,TDbQuery aCriteria)
   779 	{
   780 	return iCursor->FindL(aDirection,aCriteria);
   781 	}
   782 
   783 /** Tests whether the current row in the rowset matches a previously compiled row 
   784 constraint. The rowset must not currently be updating or inserting a row.
   785 
   786 @param aConstraint A row constraint object which must have been previously 
   787 opened on this rowset object.
   788 @return ETrue if the current row fulfils the constraint, otherwise EFalse. 
   789 
   790 @capability Note For a secure shared database, the caller must satisfy the read
   791             access policy for the table.
   792 */
   793 EXPORT_C TBool RDbRowSet::MatchL(const RDbRowConstraint& aConstraint)
   794 	{
   795 	return iCursor->MatchL(*aConstraint.iConstraint);
   796 	}
   797 
   798 // Class RDbRowConstraint
   799 
   800 /** Compiles the specified SQL search-condition for matching against rows in the 
   801 specified rowset. The text comparison supplied in aCriteria is used for all 
   802 text columns in the constraint.
   803 
   804 @param aView The rowset to which the constraint will apply.
   805 @param aCriteria The SQL string and the text comparison mode for the constraint.
   806 @return KErrNone, if successful, otherwise one of the system-wide error codes. 
   807 Specifically:KErrNotFound if a column name in the SQL query does not exist.KErrArgument 
   808 if Invalid or unrecognised SQL syntax was used.KErrGeneral for a column type 
   809 mismatch in a predicate in the SQL query or if a date-literal in the SQL query 
   810 was invalid.KErrOverflow if a number-literal in the SQL query for an integral 
   811 column was too large (did not fit in a 32-bit integral representation). This 
   812 can also be one of the DBMS database error codes. 
   813 
   814 @capability Note For a secure shared database, the caller must satisfy the read
   815             access policy for the table.
   816 */
   817 EXPORT_C TInt RDbRowConstraint::Open(const RDbRowSet& aView,TDbQuery aCriteria)
   818 	{
   819 	TRAPD(r,iConstraint=aView.iCursor->ConstraintL(aCriteria));
   820 	return r;
   821 	}
   822 
   823 /** Releases the resources used by the constraint before discarding the constraint 
   824 object. */
   825 EXPORT_C void RDbRowConstraint::Close()
   826 	{
   827 	iConstraint.Close();
   828 	}
   829 
   830 // Class RDbColReadStream
   831 
   832 /** Opens the column with the specified ordinal in the specified current row in 
   833 the rowset. The row must have previously been read into the rowset using RDbRowSet::GetL().
   834 
   835 @param aView The rowset which has the row and column to be read.
   836 @param aCol The column ordinal of the column to be read 
   837 
   838 @capability Note For a secure shared database, the caller must satisfy the read
   839             access policy for the table.
   840 */
   841 EXPORT_C void RDbColReadStream::OpenL(const RDbRowSet& aView,TDbColNo aCol)
   842 	{
   843 	Attach(aView.ColSourceL(aCol));
   844 	}
   845 
   846 /** Opens the column with the specified ordinal in the specified current row in 
   847 the rowset and puts a pointer to the column on the cleanup stack.
   848 
   849 The row must have previously been read into the rowset using RDbRowSet::GetL().
   850 
   851 @param aView The rowset which has the row and column to be read.
   852 @param aCol The column ordinal of the column to be read. 
   853 
   854 @capability Note For a secure shared database, the caller must satisfy the read
   855             access policy for the table.
   856 */
   857 EXPORT_C void RDbColReadStream::OpenLC(const RDbRowSet& aView,TDbColNo aCol)
   858 	{
   859 	OpenL(aView,aCol);
   860 	PushL();
   861 	}
   862 
   863 // Class RDbColWriteStream
   864 
   865 /** Opens the column with the specified ordinal in the current row, and in the 
   866 specified rowset, and prepares the column for being written or replaced. The 
   867 rowset must be updating or inserting a row.
   868 
   869 @param aView The rowset which has the row and column to be written.
   870 @param aCol The column ordinal of the column to be written. 
   871 
   872 @capability Note For a secure shared database, the caller must satisfy the write
   873             access policy for the table.
   874 */
   875 EXPORT_C void RDbColWriteStream::OpenL(RDbRowSet& aView,TDbColNo aCol)
   876 	{
   877 	Attach(aView.ColSinkL(aCol));
   878 	}
   879 
   880 /** Opens the column with the specified ordinal in the current row, and in the 
   881 specified rowset, and prepares the column for being written or replaced, putting 
   882 a cleanup item for this object onto the cleanup stack. The rowset must be 
   883 updating or inserting a row. 
   884 
   885 Placing the cleanup object on the cleanup stack allows allocated resources 
   886 to be cleaned up if a subsequent leave occurs.
   887 
   888 @param aView The rowset which has the row and column to be written.
   889 @param aCol The column ordinal of the column to be written. 
   890 
   891 @capability Note For a secure shared database, the caller must satisfy the write
   892             access policy for the table.
   893 */
   894 EXPORT_C void RDbColWriteStream::OpenLC(RDbRowSet& aView,TDbColNo aCol)
   895 	{
   896 	OpenL(aView,aCol);
   897 	PushL();
   898 	}
   899 
   900 // Class TDbWindow
   901 
   902 /** Constructs this object with the preferred shape. When fully evaluated, the 
   903 view will try to have aForeSlots rows immediately available for navigation 
   904 forwards, and aRearSlots rows immediately available for navigation backwards.
   905 
   906 @param aForeSlots The number of rows to evaluate ahead of the current row.
   907 @param aRearSlots The number of rows to evaluate behind the current row. */
   908 EXPORT_C TDbWindow::TDbWindow(TInt aForeSlots,TInt aRearSlots)
   909 	: iSize(aForeSlots+aRearSlots+1), iPreferredPos(aRearSlots)
   910 	{
   911 	__ASSERT_ALWAYS(aForeSlots>=0 && aRearSlots>=0,Panic(EDbInvalidViewWindowParameters));
   912 	}
   913 
   914 // Class RDbView
   915 
   916 /** Prepares the view object for evaluating an SQL select-statement.
   917 
   918 Following preparation, the rowset object can always provide schema information, 
   919 but the view may first require evaluation to generate the rowset for navigation.
   920 
   921 @param aDatabase The database on which to execute the query.
   922 @param aQuery The SQL query and the text comparison mode for the constraint.
   923 @param anAccess The access specification for the rowset. By default, updatable 
   924 access is given.
   925 @return KErrNone, if successful, otherwise one of the other system-wide error 
   926 codes. Specifically: KErrNotFound if The table does not exist in the database 
   927 or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification 
   928 in the SQL query cannot be provided by an index.KErrArgument if an invalid 
   929 or unrecognised SQL syntax was used.KErrGeneral if there is a column type 
   930 mismatch in a predicate in the SQL query or if a date-literal in the SQL query 
   931 was invalid.KErrOverflow if a number-literal in the SQL query for an integral 
   932 column was too large (did not fit in a 32-bit integral representation). This 
   933 can also be one of the DBMS database error codes.. 
   934 
   935 @capability Note For a secure shared database, the caller must satisfy the read
   936             access policy for the table.
   937 */
   938 EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,TAccess anAccess)
   939 	{
   940 	return Prepare(aDatabase,aQuery,TDbWindow(),anAccess);
   941 	}
   942 
   943 /** Prepares the view object for evaluating an SQL select-statement and specifies 
   944 the evaluation window shape for the rowset.
   945 
   946 The function does not specify the access specification for the rowset
   947 updatable access is given.
   948 
   949 Following preparation, the rowset object can always provide schema information, 
   950 but the view may first require evaluation to generate the rowset for navigation.
   951 
   952 @param aDatabase The database on which to execute the query.
   953 @param aQuery The SQL query and the text comparison mode for the constraint.
   954 @param aWindow The desired evaluation window shape for the rowset. If this 
   955 parameter is omitted, an alternative overload is called e.g. no pre-evaluation 
   956 window is requested.
   957 @return KErrNone, if successful, otherwise one of the other system-wide error 
   958 codes. Specifically: KErrNotFound if The table does not exist in the database 
   959 or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification 
   960 in the SQL query cannot be provided by an index.KErrArgument if an invalid 
   961 or unrecognised SQL syntax was used.KErrGeneral if there is a column type 
   962 mismatch in a predicate in the SQL query or if a date-literal in the SQL query 
   963 was invalid.KErrOverflow if a number-literal in the SQL query for an integral 
   964 column was too large (did not fit in a 32-bit integral representation). This 
   965 can also be one of the DBMS database error codes. 
   966 
   967 @capability Note For a secure shared database, the caller must satisfy the read
   968             access policy for the table.
   969 */
   970 EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,const TDbWindow& aWindow)
   971 	{
   972 	return Prepare(aDatabase,aQuery,aWindow,EUpdatable);
   973 	}
   974 
   975 /** Prepares the view object for evaluating an SQL select-statement, specifies 
   976 the evaluation window shape for the rowset, and sets the access specification 
   977 for the rowset.
   978 
   979 Following preparation, the rowset object can always provide schema information, 
   980 but the view may first require evaluation to generate the rowset for navigation.
   981 
   982 @param aDatabase The database on which to execute the query.
   983 @param aQuery The SQL query and the text comparison mode for the constraint.
   984 @param aWindow The desired evaluation window shape for the rowset. If this 
   985 parameter is omitted, an alternative overload is called e.g. no pre-evaluation 
   986 window is requested.
   987 @param anAccess The access specification for the rowset. If omitted, updatable 
   988 access is given.
   989 @return KErrNone, if successful, otherwise one of the other system-wide error 
   990 codes. Specifically:KErrNotFound if The table does not exist in the database 
   991 or a column name in the SQL query does not exist.KErrNotSupported if a sort-specification 
   992 in the SQL query cannot be provided by an index.KErrArgument if an invalid 
   993 or unrecognised SQL syntax was used.KErrGeneral if there is a column type 
   994 mismatch in a predicate in the SQL query or if a date-literal in the SQL query 
   995 was invalid.KErrOverflow if a number-literal in the SQL query for an integral 
   996 column was too large (did not fit in a 32-bit integral representation). This 
   997 can also be one of the DBMS database error codes. 
   998 
   999 @capability Note For a secure shared database, the caller must satisfy the read
  1000             access policy for the table.
  1001 */
  1002 EXPORT_C TInt RDbView::Prepare(RDbDatabase& aDatabase,const TDbQuery& aQuery,const TDbWindow& aWindow,TAccess anAccess)
  1003 	{
  1004 	TRAPD(r,iCursor=aDatabase.iDatabase->ViewL(aQuery,aWindow,anAccess));
  1005 	return r;
  1006 	}
  1007 
  1008 /** Use this function to fully evaluate the view. It is equivalent to:
  1009 
  1010 while (Unevaluated()) { Evaluate(); }
  1011 
  1012 @return KErrNone, if successful, otherwise one of the system wide error codes. */
  1013 EXPORT_C TInt RDbView::EvaluateAll()
  1014 	{
  1015 	TInt r;
  1016 	do r=Evaluate(); while (r>0);
  1017 	return r;
  1018 	}
  1019 
  1020 /** Performs a single step of the view evaluation, and returns when the step is 
  1021 complete. To completely evaluate a view in one go, EvaluateAll() should be 
  1022 used.
  1023 
  1024 @return 0, evaluation is complete.> 0, more evaluation can be done. < 0, an 
  1025 error code, see the class overview for more information. */
  1026 EXPORT_C TInt RDbView::Evaluate()
  1027 	{
  1028 	return iCursor->Evaluate();
  1029 	}
  1030 
  1031 /** Performs a single step of the view evaluation, returning immediately and signalling 
  1032 when the step is complete.
  1033 
  1034 This function is most effectively used when the view evaluation is carried 
  1035 out from an active object. 
  1036 
  1037 @param aStatus The request status used to contain completion information for 
  1038 the function. On completion, the status value should be interpreted as follows: 
  1039 0, evaluation is complete.> 0, more evaluation can be done. < 0, an error 
  1040 code, see the class overview for more information. */
  1041 EXPORT_C void RDbView::Evaluate(TRequestStatus& aStatus)
  1042 	{
  1043 	iCursor->Evaluate(aStatus);
  1044 	}
  1045 
  1046 /** Tests whether any more evaluation can be done to a view.
  1047 
  1048 @return ETrue, if the view can be further evaluated; EFalse, if evaluation will 
  1049 have no effect. */
  1050 EXPORT_C TBool RDbView::Unevaluated() const
  1051 	{
  1052 	return iCursor->Unevaluated();
  1053 	}
  1054 
  1055 // Class RDbTable
  1056 
  1057 /** Opens the named table object on a database with the specified access.
  1058 
  1059 If successful, the rowset is positioned to the beginning.
  1060 
  1061 @param aDatabase The database on which to open the table.
  1062 @param aName The name of the table to open.
  1063 @param anAccess The access specification for the rowset, the default is updatable 
  1064 access.
  1065 @return KErrNone, if successful, otherwise one of the system-wide error codes. 
  1066 Specifically:KErrNotFound if the table does not exist in the database.KErrAccessDenied 
  1067 if an incremental operation is in progress. This can also be one of the DBMS 
  1068 database error codes. 
  1069 
  1070 @capability Note For a secure shared database, the caller must satisfy either the read
  1071             or the write access policy for the table.
  1072 */
  1073 EXPORT_C TInt RDbTable::Open(RDbDatabase &aDatabase,const TDesC &aName,TAccess anAccess)
  1074 	{
  1075 	TRAPD(r,iCursor=aDatabase.iDatabase->TableL(aName,anAccess));
  1076 	return r;
  1077 	}
  1078 
  1079 /** Sets the specified index as the active index for this table. The rows will 
  1080 be presented in index order, and this index key will be used for lookup by 
  1081 the SeekL() function.
  1082 
  1083 If successful, the rowset is reset to the beginning.
  1084 
  1085 @param anIndex The name of the index to activate.
  1086 @return KErrNone, if successful, otherwise one of the system-wide error codes. 
  1087 Specifically:KErrWrite if the table was created with insert-only access.KErrNotFound 
  1088 if the index does not exist on the table. This can also be one of the DBMS 
  1089 database error codes. 
  1090 
  1091 @capability Note For a secure shared database, the caller must satisfy the read
  1092             access policy for the table.
  1093 */
  1094 EXPORT_C TInt RDbTable::SetIndex(const TDesC* anIndex)
  1095 	{
  1096 	TRAPD(r,iCursor->SetIndexL(anIndex));
  1097 	return r;
  1098 	}
  1099 
  1100 /** Finds a row in a table based on a key in the active index.
  1101 
  1102 This function cannot be called while the rowset is currently updating or inserting 
  1103 a row. The currently active index on the table must have a key definition 
  1104 which matches the types in the key value.
  1105 
  1106 Less columns can be added to the key than are present in the index definition: 
  1107 the keys will only be compared up to the columns present further columns 
  1108 in the index are not considered.
  1109 
  1110 If successful the cursor is positioned to the row which was found, otherwise 
  1111 the cursor is left on an invalid row.
  1112 
  1113 The underlying Store database can leave with KErrWrite, if the table was created 
  1114 with insert-only access.
  1115 
  1116 The function can also leave with one of the DBMS database error codes.
  1117 
  1118 @param aKey The key value to lookup in the index.
  1119 @param aComparison The comparison operation for the lookup, the default is 
  1120 to look for an exact match (EEqualTo).
  1121 @return ETrue if a row which compares correctly with the key exists, EFalse if 
  1122 not. 
  1123 
  1124 @capability Note For a secure shared database, the caller must satisfy the read
  1125             access policy for the table.
  1126 */
  1127 EXPORT_C TBool RDbTable::SeekL(const TDbSeekKey& aKey,TComparison aComparison)
  1128 	{
  1129 	__ASSERT_ALWAYS(aKey.iKey.Count()>0,Panic(EDbNoColumnsInSeekKey));
  1130 	return iCursor->SeekL(aKey.iKey,aComparison);
  1131 	}
  1132 
  1133 // Class CDbCursor
  1134 
  1135 //
  1136 // Default implementation in terms of ColumnDef. Might be inefficient
  1137 //
  1138 EXPORT_C void CDbCursor::ColumnsL(CDbColSet& aColSet)
  1139 	{
  1140 	TDbCol col;
  1141 	TDbColNo max=ColumnCount();
  1142 	for (TDbColNo ii=0;++ii<=max;)
  1143 		{
  1144 		ColumnDef(col,ii);
  1145 		aColSet.AddL(col);
  1146 		}
  1147 	}
  1148 
  1149 //
  1150 // Default implementation in terms of navigation
  1151 // Faster counting may be possible
  1152 //
  1153 EXPORT_C TInt CDbCursor::CountL(RDbRowSet::TAccuracy)
  1154 	{
  1155 	TDbBookmark::TMark mark;
  1156 	Bookmark(mark);
  1157 	GotoL(RDbRowSet::EBeginning);
  1158 	TInt count=0;
  1159 	while (GotoL(RDbRowSet::ENext))
  1160 		++count;
  1161 	GotoL(mark);
  1162 	return count;
  1163 	}
  1164 
  1165 //
  1166 //  Default implementation in terms of constraints
  1167 //
  1168 EXPORT_C TInt CDbCursor::FindL(RDbRowSet::TDirection aDirection,const TDbQuery& aCriteria)
  1169 	{
  1170 	CDbRowConstraint* constraint=ConstraintL(aCriteria);
  1171 	constraint->PushL();
  1172 	RDbRowSet::TPosition next=aDirection==RDbRowSet::EForwards ? RDbRowSet::ENext : RDbRowSet::EPrevious;
  1173 	TInt skip=0;
  1174 	do
  1175 		{
  1176 		if (MatchL(*constraint))
  1177 			{
  1178 			CleanupStack::PopAndDestroy();	// constraint
  1179 			return skip;
  1180 			}
  1181 		++skip;
  1182 		} while (GotoL(next));
  1183 	CleanupStack::PopAndDestroy();
  1184 	return KErrNotFound;
  1185 	}
  1186 
  1187 TInt CDbCursor::Evaluate()
  1188 	{
  1189 	TRAPD(r,r=EvaluateL());
  1190 	return r;
  1191 	}
  1192 
  1193 CDbRowConstraint* CDbCursor::ConstraintL(const TDbQuery& aQuery)
  1194 	{
  1195 	return AttachContext(this,OpenConstraintL(aQuery));
  1196 	}
  1197 
  1198 //
  1199 // Reserved for future development
  1200 //
  1201 EXPORT_C void CDbCursor::Reserved_1()
  1202 	{
  1203 	}
  1204 
  1205 //
  1206 // Reserved for future development
  1207 //
  1208 EXPORT_C void CDbCursor::Reserved_2()
  1209 	{
  1210 	}