persistentstorage/dbms/tdbms/t_dbsql.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 // MSVC++ up to 5.0 has problems with expanding inline functions
       
    17 // This disables the mad warnings for the whole project
       
    18 #if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100
       
    19 #pragma warning(disable : 4710)			// function not expanded. MSVC 5.0 is stupid
       
    20 #endif
       
    21 
       
    22 #include <d32dbms.h>
       
    23 #include <f32file.h>
       
    24 #include <e32test.h>
       
    25 #include <e32math.h>
       
    26 
       
    27 // constructing literal TInt64 from compiler 64 bit integer rep
       
    28 
       
    29 #ifndef I64LIT
       
    30 #if defined __GCC32__ || defined __EABI__
       
    31 #define _LINT64(val) MAKE_TINT64(TUint(val##LL>>32),TUint(val##LL&0xffffffffu))
       
    32 #else
       
    33 #define _LINT64(val) MAKE_TINT64(TUint(__int64(val)>>32),TUint(__int64(val)&0xffffffffu))
       
    34 #endif
       
    35 #else // I64LIT
       
    36 #define _LINT64 I64LIT
       
    37 #endif // I64LIT
       
    38 
       
    39 LOCAL_D RTest TheTest(_L("t_dbsql: DBMS SQL parsing and execution tests"));
       
    40 
       
    41 LOCAL_D RFs TheFs;
       
    42 LOCAL_D CTrapCleanup* TheTrapCleanup;
       
    43 LOCAL_D RDbs TheDbs;
       
    44 LOCAL_D RDbNamedDatabase TheDatabase;
       
    45 LOCAL_D RDbTable TheTable;
       
    46 LOCAL_D RDbView TheView;
       
    47 LOCAL_D TBuf<1024> TheSql;
       
    48 
       
    49 const TInt KTestCleanupStack=0x20;
       
    50 const TPtrC KTestDatabase=_L("c:\\dbms-tst\\t_sql.db");
       
    51 
       
    52 #define elementsof(array) (sizeof(array)/sizeof(array[0]))
       
    53 
       
    54 LOCAL_C void TestCleanup()
       
    55 	{
       
    56 	TheTable.Close();
       
    57 	TheView.Close();
       
    58 	TheDatabase.Close();
       
    59 	TheDbs.Close();
       
    60 	TheFs.Close();
       
    61 	/////////////
       
    62 	RFs fsSession;
       
    63 	TInt err = fsSession.Connect();
       
    64 	if(err == KErrNone)
       
    65 		{
       
    66 		TEntry entry;
       
    67 		if(fsSession.Entry(KTestDatabase, entry) == KErrNone)
       
    68 			{
       
    69 			RDebug::Print(_L("Deleting \"%S\" file.\n"), &KTestDatabase);
       
    70 			err = fsSession.SetAtt(KTestDatabase, 0, KEntryAttReadOnly);
       
    71 			if(err != KErrNone)
       
    72 				{
       
    73 				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &KTestDatabase);
       
    74 				}
       
    75 			err = fsSession.Delete(KTestDatabase);
       
    76 			if(err != KErrNone)
       
    77 				{
       
    78 				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &KTestDatabase);
       
    79 				}
       
    80 			}
       
    81 		fsSession.Close();
       
    82 		}
       
    83 	else
       
    84 		{
       
    85 		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &KTestDatabase);
       
    86 		}
       
    87 	}
       
    88 
       
    89 LOCAL_C void CloseDatabase()
       
    90 	{
       
    91 	TheDatabase.Close();
       
    92 	}
       
    93 
       
    94 LOCAL_C void Disconnect()
       
    95 	{
       
    96 	TheDbs.ResourceCheck();
       
    97 	TheDbs.Close();
       
    98 	}
       
    99 
       
   100 ///////////////////////////////////////////////////////////////////////////////////////
       
   101 ///////////////////////////////////////////////////////////////////////////////////////
       
   102 //Tests macros and functions.
       
   103 //If (!aValue) then the test will be panicked, the test data files will be deleted.
       
   104 static void Check(TInt aValue, TInt aLine)
       
   105 	{
       
   106 	if(!aValue)
       
   107 		{
       
   108         RDebug::Print(_L("*** Expression evaluated to false\r\n"));
       
   109 		::TestCleanup();
       
   110 		TheTest(EFalse, aLine);
       
   111 		}
       
   112 	}
       
   113 //If (aValue != aExpected) then the test will be panicked, the test data files will be deleted.
       
   114 static void Check(TInt aValue, TInt aExpected, TInt aLine)
       
   115 	{
       
   116 	if(aValue != aExpected)
       
   117 		{
       
   118 		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
   119 		::TestCleanup();
       
   120 		TheTest(EFalse, aLine);
       
   121 		}
       
   122 	}
       
   123 //Use these to test conditions.
       
   124 #define TEST(arg) ::Check((arg), __LINE__)
       
   125 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
   126 
       
   127 ///////////////////////////////////////////////////////////////////////////////////////
       
   128 ///////////////////////////////////////////////////////////////////////////////////////
       
   129 
       
   130 // Create the database
       
   131 LOCAL_C void CreateDatabase()
       
   132 	{
       
   133 	TInt r=TheDatabase.Replace(TheFs,KTestDatabase);
       
   134 	TEST2(r, KErrNone);
       
   135 	}
       
   136 
       
   137 LOCAL_C void Connect()
       
   138 	{
       
   139 	TInt r=TheDbs.Connect();
       
   140 	TEST2(r, KErrNone);
       
   141 	TheDbs.ResourceMark();
       
   142 	}
       
   143 
       
   144 // Open the database through the server
       
   145 LOCAL_C void ShareDatabase()
       
   146 	{
       
   147 	TInt r=TheDatabase.Open(TheDbs,KTestDatabase);
       
   148 	TEST2(r, KErrNone);
       
   149 	}
       
   150 
       
   151 struct TSelectTest
       
   152 	{
       
   153 	const TText* iSearchCondition;
       
   154 	TUint iResultSet;
       
   155 	};
       
   156 #define ROWS(n,m) (((~0u)<<(n))&((2u<<(m))-1))
       
   157 #define ROW(n) ROWS(n,n)
       
   158 #define NO_ROWS 0
       
   159 #define ALL_ROWS (~1u)		// all rows which are not NULL
       
   160 
       
   161 class TestPredicateBase
       
   162 	{
       
   163 protected:
       
   164 	static void Create(const TText* aType);
       
   165 	static void Test(const TSelectTest* aTest,TInt aCount,TInt aRows);
       
   166 	static void TestViewL(const TSelectTest* aTest,TInt aCount,TInt aRows);
       
   167 	};
       
   168 
       
   169 // Create the table for the predicate tests
       
   170 void TestPredicateBase::Create(const TText* aType)
       
   171 	{
       
   172 	TheTest.Next(TPtrC(aType));
       
   173 	TheDatabase.Begin();
       
   174 	TheSql.Format(_L("CREATE TABLE Compare (Id COUNTER,Test %s)"),aType);
       
   175 	TInt r=TheDatabase.Execute(TheSql);
       
   176 	TEST2(r, KErrNone);
       
   177 	r=TheTable.Open(TheDatabase,_L("Compare"),TheTable.EInsertOnly);
       
   178 	TEST2(r, KErrNone);
       
   179 	}
       
   180 
       
   181 // Test the predicate on the table, then on the indexed table
       
   182 void TestPredicateBase::Test(const TSelectTest* aTest,TInt aCount,TInt aRows)
       
   183 	{
       
   184 	TheTable.Close();
       
   185 	TInt r=TheDatabase.Commit();
       
   186 	TEST2(r, KErrNone);
       
   187 	TRAPD(errCode, TestViewL(aTest,aCount,aRows));
       
   188 	TEST2(errCode, KErrNone);
       
   189 	r=TheDatabase.Execute(_L("CREATE INDEX Key ON Compare (Test)"));
       
   190 	TEST2(r, KErrNone);
       
   191 	TRAP(errCode,TestViewL(aTest,aCount,aRows));
       
   192 	TEST2(errCode, KErrNone);
       
   193 	r=TheDatabase.Execute(_L("DROP TABLE Compare"));
       
   194 	TEST2(r, KErrNone);
       
   195 	}
       
   196 
       
   197 // Test the predicate on the table
       
   198 void TestPredicateBase::TestViewL(const TSelectTest* aTest,TInt aCount,TInt aRows)
       
   199 	{
       
   200 	TUint rowMask=(2u<<aRows)-1;
       
   201 	for (;--aCount>=0;++aTest)
       
   202 		{
       
   203 		TheSql.Format(_L("SELECT Id FROM Compare WHERE Test %s"),aTest->iSearchCondition);
       
   204 		TInt r=TheView.Prepare(TheDatabase,TheSql,TheView.EReadOnly);
       
   205 
       
   206 		TBool ignoreRow0=TheView.Unevaluated();
       
   207 		TEST2(r, KErrNone);
       
   208 		r=TheView.EvaluateAll();
       
   209 		TEST2(r, KErrNone);
       
   210 		TUint rows=0;
       
   211 		while (TheView.NextL())
       
   212 			{
       
   213 			TheView.GetL();
       
   214 			rows|=1u<<TheView.ColUint(1);
       
   215 			}
       
   216 		if (ignoreRow0)
       
   217 			TEST((rows&~ROW(0))==(aTest->iResultSet&rowMask&~ROW(0)));
       
   218 		else
       
   219 			TEST(rows==(aTest->iResultSet&rowMask));
       
   220 		TheView.Close();
       
   221 		}
       
   222 	}
       
   223 
       
   224 typedef void (*FSetColL)(TDbColNo aCol,const TAny* aVal);
       
   225 
       
   226 void WriteRowsL(const TAny* aValues,TInt aRows,TInt aSize,FSetColL aSetColL)
       
   227 	{
       
   228 	for (TInt row=0;row<=aRows;++row)
       
   229 		{
       
   230 		TheTable.InsertL();
       
   231 		TEST(TheTable.ColUint(1)==TUint(row));
       
   232 		if (row>0)
       
   233 			{	// first row is always null
       
   234 			aSetColL(2,aValues);
       
   235 			aValues=PtrAdd(aValues,aSize);
       
   236 			}
       
   237 		TheTable.PutL();
       
   238 		}
       
   239 	}
       
   240 
       
   241 template <class T>
       
   242 struct SetCol
       
   243 	{
       
   244 	static void SetColL(TDbColNo aCol,const TAny* aVal)
       
   245 		{
       
   246 		TheTable.SetColL(aCol,*(const T*)aVal);
       
   247 		}
       
   248 	};
       
   249 
       
   250 template <class T>
       
   251 inline void WriteRowsL(const T* aValues,TUint aRows)
       
   252 	{
       
   253 	WriteRowsL(aValues,aRows,sizeof(T),&SetCol<T>::SetColL);
       
   254 	}
       
   255 
       
   256 template <class T>
       
   257 class TestPredicate : public TestPredicateBase
       
   258 	{
       
   259 public:
       
   260 	static void RunL();
       
   261 	};
       
   262 
       
   263 // Test the Predicate operators for all types
       
   264 template <class T>
       
   265 void TestPredicate<T>::RunL()
       
   266 	{
       
   267 	Create(T::KType);
       
   268 	WriteRowsL(T::KValues,elementsof(T::KValues));
       
   269 	Test(T::KTests,elementsof(T::KTests),elementsof(T::KValues));
       
   270 	}
       
   271 
       
   272 struct TypeBit
       
   273 	{
       
   274 public:
       
   275 	static const TText* const KType;
       
   276 	static const TUint KValues[];
       
   277 	static const TSelectTest KTests[];
       
   278 	};
       
   279 const TText* const TypeBit::KType=_S("BIT");
       
   280 const TUint TypeBit::KValues[]={0,1};
       
   281 const TSelectTest TypeBit::KTests[]=
       
   282 	{
       
   283 	{_S("IS NULL"),ROW(0)},
       
   284 	{_S("IS NOT NULL"),ALL_ROWS},
       
   285 	{_S("=0"),ROW(1)},
       
   286 	{_S("<>0"),ROW(2)},
       
   287 	{_S(">0"),ROW(2)},
       
   288 	{_S("<0"),NO_ROWS},
       
   289 	{_S("<=0"),ROW(1)},
       
   290 	{_S(">=0"),ALL_ROWS},
       
   291 	{_S("=1"),ROW(2)},
       
   292 	{_S("<>1"),ROW(1)},
       
   293 	{_S(">1"),NO_ROWS},
       
   294 	{_S("<1"),ROW(1)},
       
   295 	{_S("<=1"),ALL_ROWS},
       
   296 	{_S(">=1"),ROW(2)}
       
   297 	};
       
   298 
       
   299 struct TypeUint8
       
   300 	{
       
   301 public:
       
   302 	static const TText* const KType;
       
   303 	static const TUint KValues[];
       
   304 	static const TSelectTest KTests[];
       
   305 	};
       
   306 const TText* const TypeUint8::KType=_S("UNSIGNED TINYINT");
       
   307 const TUint TypeUint8::KValues[]={0,1,127,128,254,255};
       
   308 const TSelectTest TypeUint8::KTests[]=
       
   309 	{
       
   310 	{_S("IS NULL"),ROW(0)},
       
   311 	{_S("IS NOT NULL"),ALL_ROWS},
       
   312 	{_S("=0"),ROW(1)},
       
   313 	{_S("=3"),NO_ROWS},
       
   314 	{_S("<2"),ROWS(1,2)},
       
   315 	{_S(">=0"),ALL_ROWS},
       
   316 	{_S("<128"),ROWS(1,3)},
       
   317 	{_S("<>1"),ALL_ROWS-ROW(2)},
       
   318 	{_S(">255"),NO_ROWS}
       
   319 	};
       
   320 
       
   321 struct TypeUint16
       
   322 	{
       
   323 public:
       
   324 	static const TText* const KType;
       
   325 	static const TUint KValues[];
       
   326 	static const TSelectTest KTests[];
       
   327 	};
       
   328 const TText* const TypeUint16::KType=_S("UNSIGNED SMALLINT");
       
   329 const TUint TypeUint16::KValues[]={0,1,5000,32767,32768,65534,65535};
       
   330 const TSelectTest TypeUint16::KTests[]=
       
   331 	{
       
   332 	{_S("IS NULL"),ROW(0)},
       
   333 	{_S("IS NOT NULL"),ALL_ROWS},
       
   334 	{_S("=0"),ROW(1)},
       
   335 	{_S("=3"),NO_ROWS},
       
   336 	{_S("<2"),ROWS(1,2)},
       
   337 	{_S(">=32768"),ROWS(5,7)},
       
   338 	{_S("<32767"),ROWS(1,3)},
       
   339 	{_S("<>1"),ALL_ROWS-ROW(2)},
       
   340 	{_S(">65535"),NO_ROWS}
       
   341 	};
       
   342 
       
   343 struct TypeUint32
       
   344 	{
       
   345 public:
       
   346 	static const TText* const KType;
       
   347 	static const TUint KValues[];
       
   348 	static const TSelectTest KTests[];
       
   349 	};
       
   350 const TText* const TypeUint32::KType=_S("UNSIGNED INTEGER");
       
   351 const TUint TypeUint32::KValues[]={0,1,2147483647u,2147483648u,3000000000u,4294967294u,4294967295u};
       
   352 const TSelectTest TypeUint32::KTests[]=
       
   353 	{
       
   354 	{_S("IS NULL"),ROW(0)},
       
   355 	{_S("IS NOT NULL"),ALL_ROWS},
       
   356 	{_S("=0"),ROW(1)},
       
   357 	{_S("=3"),NO_ROWS},
       
   358 	{_S("<2"),ROWS(1,2)},
       
   359 	{_S(">=2147483648"),ROWS(4,7)},
       
   360 	{_S("<2147483647"),ROWS(1,2)},
       
   361 	{_S("<>3000000000"),ALL_ROWS-ROW(5)},
       
   362 	{_S(">4294967295"),NO_ROWS}
       
   363 	};
       
   364 
       
   365 struct TypeInt8
       
   366 	{
       
   367 public:
       
   368 	static const TText* const KType;
       
   369 	static const TInt KValues[];
       
   370 	static const TSelectTest KTests[];
       
   371 	};
       
   372 const TText* const TypeInt8::KType=_S("TINYINT");
       
   373 const TInt TypeInt8::KValues[]={-128,-1,0,1,127};
       
   374 const TSelectTest TypeInt8::KTests[]=
       
   375 	{
       
   376 	{_S("IS NULL"),ROW(0)},
       
   377 	{_S("IS NOT NULL"),ALL_ROWS},
       
   378 	{_S("=0"),ROW(3)},
       
   379 	{_S("=-1"),ROW(2)},
       
   380 	{_S("<2"),ROWS(1,4)},
       
   381 	{_S(">=-128"),ALL_ROWS},
       
   382 	{_S("<128"),ALL_ROWS},
       
   383 	{_S("<>1"),ALL_ROWS-ROW(4)}
       
   384 	};
       
   385 
       
   386 struct TypeInt16
       
   387 	{
       
   388 public:
       
   389 	static const TText* const KType;
       
   390 	static const TInt KValues[];
       
   391 	static const TSelectTest KTests[];
       
   392 	};
       
   393 const TText* const TypeInt16::KType=_S("SMALLINT");
       
   394 const TInt TypeInt16::KValues[]={-32768,-32767,-1,0,1,32766,32767};
       
   395 const TSelectTest TypeInt16::KTests[]=
       
   396 	{
       
   397 	{_S("IS NULL"),ROW(0)},
       
   398 	{_S("IS NOT NULL"),ALL_ROWS},
       
   399 	{_S("=0"),ROW(4)},
       
   400 	{_S("<>0"),ALL_ROWS-ROW(4)},
       
   401 	{_S("=-1"),ROW(3)},
       
   402 	{_S("<2"),ROWS(1,5)},
       
   403 	{_S(">=-40000"),ALL_ROWS},
       
   404 	{_S("<32766"),ROWS(1,5)},
       
   405 	{_S("=40"),NO_ROWS}
       
   406 	};
       
   407 
       
   408 struct TypeInt32
       
   409 	{
       
   410 public:
       
   411 	static const TText* const KType;
       
   412 	static const TInt KValues[];
       
   413 	static const TSelectTest KTests[];
       
   414 	};
       
   415 const TText* const TypeInt32::KType=_S("INTEGER");
       
   416 const TInt TypeInt32::KValues[]={0x80000000/*-2147483648*/,-2147483647,-1,0,1,2147483646,2147483647};
       
   417 const TSelectTest TypeInt32::KTests[]=
       
   418 	{
       
   419 	{_S("IS NULL"),ROW(0)},
       
   420 	{_S("IS NOT NULL"),ALL_ROWS},
       
   421 	{_S("=0"),ROW(4)},
       
   422 	{_S("<>0"),ALL_ROWS-ROW(4)},
       
   423 	{_S("=-1"),ROW(3)},
       
   424 	{_S("<2"),ROWS(1,5)},
       
   425 	{_S(">=-2147483648"),ALL_ROWS},
       
   426 	{_S("<2147483646"),ROWS(1,5)},
       
   427 	{_S(">2147483647"),NO_ROWS},
       
   428 	{_S("=40"),NO_ROWS}
       
   429 	};
       
   430 
       
   431 struct TypeInt64
       
   432 	{
       
   433 public:
       
   434 	static const TText* const KType;
       
   435 	static const TInt64 KValues[];
       
   436 	static const TSelectTest KTests[];
       
   437 	};
       
   438 const TText* const TypeInt64::KType=_S("BIGINT");
       
   439 const TInt64 TypeInt64::KValues[]=
       
   440 	{
       
   441 	MAKE_TINT64(0x80000000, 0x00000000), // min int64
       
   442 	_LINT64(-4294967296),
       
   443 	TInt(0x80000000),			// -2147483648!
       
   444 	-1,
       
   445 	0u,
       
   446 	1u,
       
   447 	2147483647u,
       
   448 	_LINT64(2147483648),
       
   449 	_LINT64(4294967295),
       
   450 	_LINT64(4294967296),
       
   451 	_LINT64(9223372036854775807)		// max int64
       
   452 	};
       
   453 const TSelectTest TypeInt64::KTests[]=
       
   454 	{
       
   455 	{_S("IS NULL"),ROW(0)},
       
   456 	{_S("IS NOT NULL"),ALL_ROWS},
       
   457 	{_S("=0"),ROW(5)},
       
   458 	{_S("<>0"),ALL_ROWS-ROW(5)},
       
   459 	{_S("=-1"),ROW(4)},
       
   460 	{_S("<2"),ROWS(1,6)},
       
   461 	{_S(">=-9223372036854775808"),ALL_ROWS},
       
   462 	{_S("<4294967296"),ROWS(1,9)},
       
   463 	{_S(">9223372036854775806"),ROW(11)},
       
   464 	{_S("=40"),NO_ROWS}
       
   465 	};
       
   466 
       
   467 struct TypeReal32
       
   468 	{
       
   469 public:
       
   470 	static const TText* const KType;
       
   471 	static const TReal32 KValues[];
       
   472 	static const TSelectTest KTests[];
       
   473 	};
       
   474 const TText* const TypeReal32::KType=_S("REAL");
       
   475 const TReal32 TypeReal32::KValues[]=
       
   476 	{
       
   477 	-KMaxTReal32,
       
   478 	-1.0f,
       
   479 	-KMinTReal32,
       
   480 	0.0f,
       
   481 	KMinTReal32,
       
   482 	1.0f,
       
   483 	KMaxTReal32
       
   484 	};
       
   485 const TSelectTest TypeReal32::KTests[]=
       
   486 	{
       
   487 	{_S("IS NULL"),ROW(0)},
       
   488 	{_S("IS NOT NULL"),ALL_ROWS},
       
   489 	{_S("=0"),ROW(4)},
       
   490 	{_S("<>0.0"),ALL_ROWS-ROW(4)},
       
   491 	{_S("=-1"),ROW(2)},
       
   492 	{_S("<2e1"),ROWS(1,6)},
       
   493 	{_S(">=-100000000000000"),ROWS(2,7)},
       
   494 	{_S("<1e-36"),ROWS(1,5)},
       
   495 	{_S(">1e15"),ROW(7)},
       
   496 	{_S("=.5"),NO_ROWS},
       
   497 	{_S("<=-.0"),ROWS(1,4)},
       
   498 	{_S("<1e40"),ALL_ROWS}
       
   499 	};
       
   500 
       
   501 struct TypeReal64
       
   502 	{
       
   503 public:
       
   504 	static const TText* const KType;
       
   505 	static const TReal64 KValues[];
       
   506 	static const TSelectTest KTests[];
       
   507 	};
       
   508 const TText* const TypeReal64::KType=_S("DOUBLE");
       
   509 const TReal64 TypeReal64::KValues[]=
       
   510 	{
       
   511 	-KMaxTReal64,
       
   512 	-1.0f,
       
   513 	-KMinTReal64,
       
   514 	0.0f,
       
   515 	KMinTReal64,
       
   516 	1.0f,
       
   517 	KMaxTReal64
       
   518 	};
       
   519 const TSelectTest TypeReal64::KTests[]=
       
   520 	{
       
   521 	{_S("IS NULL"),ROW(0)},
       
   522 	{_S("IS NOT NULL"),ALL_ROWS},
       
   523 	{_S("=0"),ROW(4)},
       
   524 	{_S("<>0"),ALL_ROWS-ROW(4)},
       
   525 	{_S("=-1"),ROW(2)},
       
   526 	{_S("<2"),ROWS(1,6)},
       
   527 	{_S(">=-100000000000000"),ROWS(2,7)},
       
   528 	{_S("<1e-300"),ROWS(1,5)},
       
   529 	{_S(">1e15"),ROW(7)},
       
   530 	{_S("=.5"),NO_ROWS},
       
   531 	{_S("<=0"),ROWS(1,4)},
       
   532 	{_S("<1e40"),ROWS(1,6)}
       
   533 	};
       
   534 
       
   535 struct TypeTime
       
   536 	{
       
   537 public:
       
   538 	static const TText* const KType;
       
   539 	static const TTime KValues[];
       
   540 	static const TSelectTest KTests[];
       
   541 	};
       
   542 const TText* const TypeTime::KType=_S("TIME");
       
   543 const TTime TypeTime::KValues[]=
       
   544 	{
       
   545 	TInt64(0u),				// zero date/time
       
   546 	_L(":085815"),			// 8:58:15am
       
   547 	_L("19181010:110000"),	// 11am, 11 Nov 1918
       
   548 	_L("19750226:"),		// midnight, 27 Mar 1975
       
   549 	_L("19961130:235959"),	// 11:59:59pm, 31 Dec 1996
       
   550 	_L("19970000:"),		// midnight, 1 Jan 1997
       
   551 	_L("19970611:210000"),	// 9pm, 12 July 1997
       
   552 	_L("19980309:214500"),	// 9:45pm, 10 April 1998
       
   553 	_L("20700608:")			// midnight, 9 July 2070
       
   554 	};
       
   555 const TSelectTest TypeTime::KTests[]=
       
   556 	{
       
   557 	{_S("IS NULL"),ROW(0)},
       
   558 	{_S("IS NOT NULL"),ALL_ROWS},
       
   559 	{_S("=#12am#"),ROW(1)},
       
   560 	{_S("<#Jan 1 2100#"),ALL_ROWS},
       
   561 	{_S("<>#31/12/1996 23:59:59#"),ALL_ROWS-ROW(5)},
       
   562 	{_S("<#9a#"),ROWS(1,2)},
       
   563 	{_S(">=#11:59:59pm, 31 Dec 1996#"),ROWS(5,9)},
       
   564 	{_S("=#9:45pm 10 April, 1998#"),ROW(8)},
       
   565 	{_S("=#8:58:15#"),ROW(2)}
       
   566 	};
       
   567 
       
   568 struct TypeText
       
   569 	{
       
   570 public:
       
   571 	static const TText* const KType;
       
   572 	static const TText* const KValues[];
       
   573 	static TSelectTest KTests[];
       
   574 	};
       
   575 const TText* const TypeText::KType=_S("VARCHAR(100)");
       
   576 const TText* const TypeText::KValues[]=
       
   577 	{
       
   578 	_S(""),					// this should be equivalent to NULL
       
   579 	_S("a"),
       
   580 	_S("aa"),
       
   581 	_S("aba"),
       
   582 	_S("like"),
       
   583 	_S("abcdefghijklmnopqrstuvwxyzlike"),
       
   584 	_S("likeabcdefghijklmnopqrstuvwxyz"),
       
   585 	_S("abcdefghijklmnopqrstuvwxyzlikeabcdefghijklmnopqrstuvwxyz"),
       
   586 	_S("abcdefghijklmnopqrstuvwxyzliveabcdefghijklmnopqrstuvwxyz"),
       
   587 	_S("l'ke"),
       
   588 	_S("'Tis")
       
   589 	};
       
   590 TSelectTest TypeText::KTests[]=
       
   591 	{
       
   592 	{_S("IS NULL"),ROWS(0,1)},
       
   593 	{_S("IS NOT NULL"),ALL_ROWS-ROW(1)},
       
   594 //
       
   595 	{_S("=''"),ROWS(0,1)},					// equivalent to IS NULL
       
   596 	{_S("<>''"),ALL_ROWS-ROW(1)},			// equivalent to IS NOT NULL
       
   597 	{_S(">''"),ALL_ROWS-ROW(1)},			// equivalent to IS NOT NULL
       
   598 	{_S("<''"),NO_ROWS},					// expression is trivially false
       
   599 	{_S("<=''"),ROWS(0,1)},
       
   600 	{_S(">=''"),ALL_ROWS+ROW(0)},			// expression is trivially true
       
   601 //
       
   602 	{_S("LIKE ''"),ROWS(0,1)},			// synonomous with IS NULL
       
   603 	{_S("NOT LIKE ''"),ALL_ROWS-ROW(1)},
       
   604 	{_S("LIKE '?*'"),ALL_ROWS-ROW(1)},	// synonomous with IS NOT NULL
       
   605 	{_S("NOT LIKE '?*'"),ROWS(0,1)},
       
   606 	{_S("LIKE '*'"),ALL_ROWS+ROW(0)},	// trivially true
       
   607 	{_S("NOT LIKE '*'"),NO_ROWS},
       
   608 //
       
   609 	{_S("='a'"),ROW(2)},
       
   610 	{_S("<'ab'"),ROWS(0,3)+ROW(11)},
       
   611 	{_S("<'abc'"),ROWS(0,4)+ROW(11)},
       
   612 	{_S("<'b'"),ROWS(0,4)+ROW(6)+ROWS(8,9)+ROW(11)},
       
   613 	{_S(">'abc'"),ROWS(5,10)},
       
   614 	{_S("='like'"),ROW(5)},
       
   615 	{_S("='l''ke'"),ROW(10)},
       
   616 	{_S("='''Tis'"),ROW(11)},
       
   617 //
       
   618 	{_S("LIKE 'a'"),ROW(2)},
       
   619 	{_S("LIKE 'a*'"),ROWS(2,4)+ROW(6)+ROWS(8,9)},
       
   620 	{_S("LIKE '*a'"),ROWS(2,4)},
       
   621 	{_S("LIKE 'a*a'"),ROWS(3,4)},
       
   622 	{_S("LIKE '*a*'"),ROWS(2,4)+ROWS(6,9)},
       
   623 //
       
   624 	{_S("LIKE 'like'"),ROW(5)},
       
   625 	{_S("LIKE 'l?ke'"),ROW(5)+ROW(10)},
       
   626 	{_S("LIKE 'like*'"),ROW(5)+ROW(7)},
       
   627 	{_S("LIKE '*like'"),ROWS(5,6)},
       
   628 	{_S("LIKE '*like*'"),ROWS(5,8)},
       
   629 	{_S("LIKE '*likeit*'"),NO_ROWS},
       
   630 	{_S("LIKE '*li?e*'"),ROWS(5,9)},
       
   631 	{_S("LIKE '?*li?e*'"),ROW(6)+ROWS(8,9)},
       
   632 	{_S("LIKE '*li?e*?'"),ROWS(7,9)},
       
   633 	{_S("LIKE '?*li?e*?'"),ROWS(8,9)},
       
   634 	{_S("LIKE '*?k?*'"),ROWS(5,10)},
       
   635 	{_S("LIKE '*?i?e*'"),ROWS(5,9)},
       
   636 //
       
   637 	{_S("LIKE '*e*'"),ROWS(5,10)},
       
   638 	{_S("LIKE '*z*k*e*'"),ROW(6)+ROW(8)},
       
   639 	{_S("LIKE '\?\?k?'"),ROW(5)+ROW(10)},
       
   640 	{_S("LIKE '\?\?k*'"),ROW(5)+ROW(7)+ROW(10)},
       
   641 	{_S("LIKE '*''*'"),ROWS(10,11)},
       
   642 	{_S("LIKE '?''\?\?'"),ROW(10)},
       
   643 	{_S("LIKE '?'"),ROW(2)},
       
   644 	{_S("LIKE '\?\?\?\?'"),ROW(5)+ROWS(10,11)},
       
   645 	{_S("LIKE '\?\?*\?\?'"),ROWS(5,11)},
       
   646 	{_S("LIKE '''*'"),ROW(11)}
       
   647 	};
       
   648 
       
   649 TEMPLATE_SPECIALIZATION struct SetCol<const TText* const>
       
   650 	{
       
   651 	static void SetColL(TDbColNo aCol,const TAny* aVal)
       
   652 		{
       
   653 		TheTable.SetColL(aCol,TPtrC(*(const TText* const*)aVal));
       
   654 		}
       
   655 	};
       
   656 TEMPLATE_SPECIALIZATION struct SetCol<const TText*>
       
   657 	{
       
   658 	static void SetColL(TDbColNo aCol,const TAny* aVal)
       
   659 		{
       
   660 		TheTable.SetColL(aCol,TPtrC(*(const TText* const*)aVal));
       
   661 		}
       
   662 	};
       
   663 
       
   664 struct TypeLongText
       
   665 	{
       
   666 public:
       
   667 	static const TText* const KType;
       
   668 	};
       
   669 const TText* const TypeLongText::KType=_S("LONG VARCHAR");
       
   670 
       
   671 class TestPredicate2 : public TestPredicateBase
       
   672 	{
       
   673 public:
       
   674 	static void RunL();
       
   675 	};
       
   676 
       
   677 // write rows equivalent to TypeText and use its tests
       
   678 void TestPredicate2::RunL()
       
   679 	{
       
   680 	Create(TypeLongText::KType);
       
   681 	TBuf<1022> fill=_S("abcdefghijklmnopqrstuvqxyz");
       
   682 	fill.AppendFill('.',fill.MaxLength()-fill.Length());
       
   683 
       
   684 	for (TInt row=0;row<=TInt(elementsof(TypeText::KValues));++row)
       
   685 		{
       
   686 		TheTable.InsertL();
       
   687 		TheTable.SetColL(1,row);
       
   688 		if (row>0)
       
   689 			{
       
   690 			RDbColWriteStream blob;
       
   691 			blob.OpenLC(TheTable,2);
       
   692 			switch (row)
       
   693 				{
       
   694 			case 0:
       
   695 				break;
       
   696 			case 1: case 2: case 3: case 4: case 5: case 10: case 11:
       
   697 				blob.WriteL(TPtrC(TypeText::KValues[row-1]));
       
   698 				break;
       
   699 			case 6:
       
   700 				blob.WriteL(fill);
       
   701 				blob.WriteL(_L("like"));
       
   702 				break;
       
   703 			case 7:
       
   704 				blob.WriteL(_L("like"));
       
   705 				blob.WriteL(fill);
       
   706 				break;
       
   707 			case 8:
       
   708 				blob.WriteL(fill);
       
   709 				blob.WriteL(_L("like"));
       
   710 				blob.WriteL(fill);
       
   711 				break;
       
   712 			case 9:
       
   713 				blob.WriteL(fill);
       
   714 				blob.WriteL(_L("live"));
       
   715 				blob.WriteL(fill);
       
   716 				break;
       
   717 				}
       
   718 			blob.CommitL();
       
   719 			CleanupStack::PopAndDestroy();
       
   720 			}
       
   721 		TheTable.PutL();
       
   722 		}
       
   723 	TheTable.Close();
       
   724 	TInt r=TheDatabase.Commit();
       
   725 	TEST2(r, KErrNone);
       
   726 	TestViewL(TypeText::KTests,elementsof(TypeText::KTests),elementsof(TypeText::KValues));
       
   727 	CDbKey& key=*CDbKey::NewLC();
       
   728 	key.AddL(TDbKeyCol(_L("Test"),120));
       
   729 	r=TheDatabase.CreateIndex(_L("Key"),_L("Compare"),key);
       
   730 	TEST2(r, KErrNone);
       
   731 	CleanupStack::PopAndDestroy();
       
   732 	TestViewL(TypeText::KTests,elementsof(TypeText::KTests),elementsof(TypeText::KValues));
       
   733 	r=TheDatabase.Execute(_L("DROP TABLE Compare"));
       
   734 	TEST2(r, KErrNone);
       
   735 	}
       
   736 
       
   737 /**
       
   738 * Utility for DEF063276 fix.
       
   739 */
       
   740 
       
   741 _LIT(KTypeTextKTests44, "Z:\\test\\TypeTextKTests44.dat");
       
   742 _LIT(KTypeTextKTests46, "Z:\\test\\TypeTextKTests46.dat");
       
   743 _LIT(KTypeTextKTests47, "Z:\\test\\TypeTextKTests47.dat");
       
   744 
       
   745 static void ReadDesc(TDes& aDes, const TDesC& aFilename, RFs& aFs)
       
   746 	{
       
   747 	RDebug::Print(_L("---ReadDesc(), aFilename=%S\r\n"), &aFilename);
       
   748 	RFile file;
       
   749 	TInt err = file.Open(aFs, aFilename, EFileRead);
       
   750 	TEST2(err, KErrNone);
       
   751 
       
   752 	TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(aDes.Ptr())), aDes.MaxSize());
       
   753 	err = file.Read(ptr);
       
   754 	TEST2(err, KErrNone);
       
   755 	aDes.SetLength(ptr.Length() / sizeof(TText));
       
   756 	file.Close();
       
   757 	}
       
   758 
       
   759 /**
       
   760 @SYMTestCaseID          SYSLIB-DBMS-CT-0633
       
   761 @SYMTestCaseDesc        Tests the Predicate operators for all types
       
   762 @SYMTestPriority        Medium
       
   763 @SYMTestActions         Attempt to check with different types
       
   764 @SYMTestExpectedResults Test must not fail
       
   765 @SYMREQ                 REQ0000
       
   766 */
       
   767 LOCAL_C void TestPredicatesL()
       
   768 	{
       
   769 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0633 init "));
       
   770 	CreateDatabase();
       
   771 	TestPredicate<TypeBit>::RunL();
       
   772 	TestPredicate<TypeUint8>::RunL();
       
   773 	TestPredicate<TypeUint16>::RunL();
       
   774 	TestPredicate<TypeUint32>::RunL();
       
   775 	TestPredicate<TypeInt8>::RunL();
       
   776 	TestPredicate<TypeInt16>::RunL();
       
   777 	TestPredicate<TypeInt32>::RunL();
       
   778 	TestPredicate<TypeInt64>::RunL();
       
   779 	TestPredicate<TypeReal32>::RunL();
       
   780 	TestPredicate<TypeReal64>::RunL();
       
   781 	TestPredicate<TypeTime>::RunL();
       
   782 
       
   783 	/**
       
   784 	* Work around for DEF063276.
       
   785 	* These literals are now loaded from Z:\test\TypeTextKTests44.dat,
       
   786 	* Z:\test\data\TypeTextKTests44.dat and Z:\test\TypeTextKTests44.dat respectively.
       
   787 	* Bullseye Coverage corrupts these literals to avoid this they are stored in files as to not be touched by Bullseye Coverage.
       
   788 	*/
       
   789 
       
   790 	TBuf<16> buf44;
       
   791 	ReadDesc(buf44, KTypeTextKTests44, TheFs);
       
   792 	TypeText::KTests[44].iSearchCondition = const_cast<TText*>(buf44.PtrZ());
       
   793 
       
   794 	TBuf<32> buf46(TypeText::KTests[46].iSearchCondition);
       
   795 	ReadDesc(buf46, KTypeTextKTests46, TheFs);
       
   796 	TypeText::KTests[46].iSearchCondition = const_cast<TText*>(buf46.PtrZ());
       
   797 
       
   798 	TBuf<32> buf47(TypeText::KTests[47].iSearchCondition);
       
   799 	ReadDesc(buf47, KTypeTextKTests47, TheFs);
       
   800 	TypeText::KTests[47].iSearchCondition = const_cast<TText*>(buf47.PtrZ());
       
   801 
       
   802 	// End fix.
       
   803 
       
   804 	TestPredicate<TypeText>::RunL();
       
   805 	TestPredicate2::RunL();
       
   806 	CloseDatabase();
       
   807 	TheTest.End();
       
   808 	}
       
   809 
       
   810 /**
       
   811 @SYMTestCaseID          SYSLIB-DBMS-CT-0634
       
   812 @SYMTestCaseDesc        DML Query test
       
   813                         Test for RDbNamedDatabase::Execute() function
       
   814 @SYMTestPriority        Medium
       
   815 @SYMTestActions         Tests for CREATE TABLE,CREATE UNIQUE INDEX,INSET INTO,UPDATE,DELETE,DROP queries
       
   816 @SYMTestExpectedResults Test must not fail
       
   817 @SYMREQ                 REQ0000
       
   818 */
       
   819 LOCAL_C void TestDataModificationlanguage()
       
   820 	{
       
   821 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0634 init "));
       
   822 	Connect();
       
   823 	ShareDatabase();
       
   824 	TInt r=TheDatabase.Execute(_L("CREATE TABLE test (ID INTEGER NOT NULL,SALARY DOUBLE)"));
       
   825 	TEST2(r, KErrNone);
       
   826 	r=TheDatabase.Execute(_L("CREATE UNIQUE INDEX key ON test (ID)"));
       
   827 	TEST2(r, KErrNone);
       
   828 
       
   829 	TheTest.Next(_L("insert-statements"));
       
   830 	r=TheDatabase.Execute(_L("INSERT INTO test VALUES (0,0)"));
       
   831 	TEST(r==1);
       
   832 	r=TheDatabase.Execute(_L("INSERT INTO test (ID) VALUES (1)"));
       
   833 	TEST(r==1);
       
   834 	r=TheDatabase.Execute(_L("INSERT INTO test (SALARY,ID) VALUES (20.4,2)"));
       
   835 	TEST(r==1);
       
   836 
       
   837 	TheTest.Next(_L("update-statements"));
       
   838 	r=TheDatabase.Execute(_L("UPDATE test SET SALARY=30000 WHERE ID=1"));
       
   839 	TEST(r==1);
       
   840 
       
   841 	TheTest.Next(_L("delete-statements"));
       
   842 	r=TheDatabase.Execute(_L("DELETE FROM test WHERE SALARY<40"));
       
   843 	TEST(r==2);
       
   844 	r=TheDatabase.Execute(_L("DELETE FROM test"));
       
   845 	TEST(r==1);
       
   846 	r=TheDatabase.Execute(_L("DROP TABLE test"));
       
   847 	TEST2(r, KErrNone);
       
   848 //
       
   849 	TheTest.Next(_L("larger table"));
       
   850 	r=TheDatabase.Execute(_L("CREATE TABLE test (ID COUNTER,DATA INTEGER)"));
       
   851 	TEST2(r, KErrNone);
       
   852 
       
   853 	TheTest.Next(_L("insert"));
       
   854 	r=TheDatabase.Begin();
       
   855 	TEST2(r, KErrNone);
       
   856 	TBuf<256> sql;
       
   857 	for (TInt ii=0;ii<100;++ii)
       
   858 		{
       
   859 		sql.Format(_L("INSERT INTO test (DATA) VALUES (%D)"),100-ii);
       
   860 		r=TheDatabase.Execute(sql);
       
   861 		TEST(r==1);
       
   862 		}
       
   863 	r=TheDatabase.Commit();
       
   864 	TEST2(r, KErrNone);
       
   865 
       
   866 	TheTest.Next(_L("update"));
       
   867 	r=TheDatabase.Execute(_L("UPDATE test SET DATA=200 WHERE ID>=40 AND ID<60"));
       
   868 	TEST(r==20);
       
   869 
       
   870 	TheTest.Next(_L("delete"));
       
   871 	r=TheDatabase.Execute(_L("DELETE FROM test WHERE DATA>90"));
       
   872 	TEST(r==30);
       
   873 
       
   874 	TheTest.Next(_L("update"));
       
   875 	r=TheDatabase.Execute(_L("UPDATE test SET DATA=-1"));
       
   876 	TEST(r==70);
       
   877 
       
   878 	TheTest.Next(_L("delete"));
       
   879 	r=TheDatabase.Execute(_L("DELETE FROM test"));
       
   880 	TEST(r==70);
       
   881 	r=TheDatabase.Execute(_L("DROP TABLE test"));
       
   882 	TEST2(r, KErrNone);
       
   883 	CloseDatabase();
       
   884 	Disconnect();
       
   885 	TheTest.End();
       
   886 	}
       
   887 
       
   888 /**
       
   889 @SYMTestCaseID          SYSLIB-DBMS-CT-0635
       
   890 @SYMTestCaseDesc        DBMS SQL parsing and execution tests.Tests for database index order
       
   891 						Test for RDbNamedDatabase::Execute() function
       
   892 @SYMTestPriority        Medium
       
   893 @SYMTestActions         Tests for order by index
       
   894 @SYMTestExpectedResults Test must not fail
       
   895 @SYMREQ                 REQ0000
       
   896 */
       
   897 LOCAL_C void TestOrderByL()
       
   898 	{
       
   899 	static const TReal TestDataSalary[]={10,34000,15000,53200,17800,240000};
       
   900 	static const TText* const TestDataNames[]={_S("gopher"),_S("james '007' bond"),_S("moneypenny"),_S("Q"),_S("james '007' bond"),_S("M")};
       
   901 //
       
   902 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0635 init "));
       
   903 	Connect();
       
   904 	ShareDatabase();
       
   905 	TheDatabase.Begin();
       
   906 	TInt r=TheDatabase.Execute(_L("CREATE TABLE test (ID INTEGER NOT NULL,SALARY DOUBLE,NAME VARCHAR)"));
       
   907 	TEST2(r, KErrNone);
       
   908 	r=TheDatabase.Execute(_L("CREATE UNIQUE INDEX key ON test (ID)"));
       
   909 	TEST2(r, KErrNone);
       
   910 
       
   911 	TheTest.Next(_L("insert data"));
       
   912 	r=TheView.Prepare(TheDatabase,_L("SELECT ID,SALARY,NAME FROM test"),TheView.EInsertOnly);
       
   913 	TEST2(r, KErrNone);
       
   914 	TInt ii;
       
   915 	for (ii=0;ii<6;++ii)
       
   916 		{
       
   917 		TheView.InsertL();
       
   918 		TheView.SetColL(1,6-ii);
       
   919 		TheView.SetColL(2,TestDataSalary[ii]);
       
   920 		TheView.SetColL(3,TPtrC(TestDataNames[ii]));
       
   921 		TheView.PutL();
       
   922 		}
       
   923 	r=TheDatabase.Commit();
       
   924 	TEST2(r, KErrNone);
       
   925 	TheView.Close();
       
   926 
       
   927 	TheTest.Next(_L("Order by <index>"));
       
   928 	// test the index is used here
       
   929 	r=TheView.Prepare(TheDatabase,_L("SELECT ID FROM test ORDER BY ID"));
       
   930 	TEST2(r, KErrNone);
       
   931 	TEST(!TheView.Unevaluated());
       
   932 	TInt c=0;
       
   933 	if (TheView.FirstL())
       
   934 		{
       
   935 		++c;
       
   936 		TheView.GetL();
       
   937 		TInt last=TheView.ColInt(1);
       
   938 		while (TheView.NextL())
       
   939 			{
       
   940 			++c;
       
   941 			TheView.GetL();
       
   942 			TInt v=TheView.ColInt(1);
       
   943 			TEST(v>last);
       
   944 			last=v;
       
   945 			}
       
   946 		}
       
   947 	TEST(c==6);
       
   948 	TEST(c==TheView.CountL());
       
   949 	TheView.Close();
       
   950 
       
   951 	TheTest.Next(_L("Order by <no-index> 1"));
       
   952 	// test that no index is used here
       
   953 	r=TheView.Prepare(TheDatabase,_L("SELECT SALARY FROM test ORDER BY SALARY"));
       
   954 	TEST2(r, KErrNone);
       
   955 	TEST(TheView.Unevaluated());
       
   956 	r=TheView.EvaluateAll();
       
   957 	TEST2(r, KErrNone);
       
   958 	c=0;
       
   959 	if (TheView.FirstL())
       
   960 		{
       
   961 		++c;
       
   962 		TheView.GetL();
       
   963 		TReal last=TheView.ColReal(1);
       
   964 		while (TheView.NextL())
       
   965 			{
       
   966 			++c;
       
   967 			TheView.GetL();
       
   968 			TReal v=TheView.ColReal(1);
       
   969 			TEST(v>=last);
       
   970 			last=v;
       
   971 			}
       
   972 		}
       
   973 	TEST(c==6);
       
   974 	TEST(c==TheView.CountL());
       
   975 	TheView.Close();
       
   976 
       
   977 	TheTest.Next(_L("Order by <no-index> 2"));
       
   978 	// test that no index is used here
       
   979 	r=TheView.Prepare(TheDatabase,_L("SELECT SALARY FROM test ORDER BY SALARY,NAME"));
       
   980 	TEST2(r, KErrNone);
       
   981 	TEST(TheView.Unevaluated());
       
   982 	r=TheView.EvaluateAll();
       
   983 	TEST2(r, KErrNone);
       
   984 	c=0;
       
   985 	if (TheView.FirstL())
       
   986 		{
       
   987 		++c;
       
   988 		TheView.GetL();
       
   989 		TReal last=TheView.ColReal(1);
       
   990 		while (TheView.NextL())
       
   991 			{
       
   992 			++c;
       
   993 			TheView.GetL();
       
   994 			TReal v=TheView.ColReal(1);
       
   995 			TEST(v>=last);
       
   996 			last=v;
       
   997 			}
       
   998 		}
       
   999 	TEST(c==6);
       
  1000 	TEST(c==TheView.CountL());
       
  1001 	TheView.Close();
       
  1002 
       
  1003 	TheTest.Next(_L("Order by <no-index> 3"));
       
  1004 	// test that no index is used here
       
  1005 	r=TheView.Prepare(TheDatabase,_L("SELECT NAME FROM test ORDER BY NAME"));
       
  1006 	TEST2(r, KErrNone);
       
  1007 	TEST(TheView.Unevaluated());
       
  1008 	r=TheView.EvaluateAll();
       
  1009 	TEST2(r, KErrNone);
       
  1010 	c=0;
       
  1011 	if (TheView.FirstL())
       
  1012 		{
       
  1013 		++c;
       
  1014 		TheView.GetL();
       
  1015 		TBuf<50> last=TheView.ColDes(1);
       
  1016 		while (TheView.NextL())
       
  1017 			{
       
  1018 			++c;
       
  1019 			TheView.GetL();
       
  1020 			TPtrC v=TheView.ColDes(1);
       
  1021 			TEST(v>=last);
       
  1022 			last=v;
       
  1023 			}
       
  1024 		}
       
  1025 	TEST(c==6);
       
  1026 	TEST(c==TheView.CountL());
       
  1027 	TheView.Close();
       
  1028 
       
  1029 	TheTest.Next(_L("Order by <no-index> 4"));
       
  1030 	// test that no index is used here
       
  1031 	r=TheView.Prepare(TheDatabase,_L("SELECT NAME FROM test ORDER BY NAME,SALARY"));
       
  1032 	TEST2(r, KErrNone);
       
  1033 	TEST(TheView.Unevaluated());
       
  1034 	r=TheView.EvaluateAll();
       
  1035 	TEST2(r, KErrNone);
       
  1036 	c=0;
       
  1037 	if (TheView.FirstL())
       
  1038 		{
       
  1039 		++c;
       
  1040 		TheView.GetL();
       
  1041 		TBuf<50> last=TheView.ColDes(1);
       
  1042 		while (TheView.NextL())
       
  1043 			{
       
  1044 			++c;
       
  1045 			TheView.GetL();
       
  1046 			TPtrC v=TheView.ColDes(1);
       
  1047 			TEST(v>=last);
       
  1048 			last=v;
       
  1049 			}
       
  1050 		}
       
  1051 	TEST(c==6);
       
  1052 	TEST(c==TheView.CountL());
       
  1053 	TheView.Close();
       
  1054 
       
  1055 	TheTest.Next(_L("Order by + search <no-index>"));
       
  1056 	// test that no index is used here
       
  1057 	r=TheView.Prepare(TheDatabase,_L("SELECT ID,SALARY FROM test WHERE SALARY>30000 ORDER BY SALARY DESC"));
       
  1058 	TEST2(r, KErrNone);
       
  1059 	TEST(TheView.Unevaluated());
       
  1060 	r=TheView.EvaluateAll();
       
  1061 	TEST2(r, KErrNone);
       
  1062 	c=0;
       
  1063 	if (TheView.FirstL())
       
  1064 		{
       
  1065 		++c;
       
  1066 		TheView.GetL();
       
  1067 		TReal last=TheView.ColReal(2);
       
  1068 		while (TheView.NextL())
       
  1069 			{
       
  1070 			++c;
       
  1071 			TheView.GetL();
       
  1072 			TReal v=TheView.ColReal(2);
       
  1073 			TEST(v<=last);
       
  1074 			last=v;
       
  1075 			}
       
  1076 		}
       
  1077 	TEST(c==3);
       
  1078 	TEST(c==TheView.CountL());
       
  1079 	TheView.Close();
       
  1080 //
       
  1081 	CloseDatabase();
       
  1082 	Disconnect();
       
  1083 
       
  1084 	TheTest.Next(_L("Order by <index> Finished"));
       
  1085 	TheTest.End();
       
  1086 	}
       
  1087 
       
  1088 LOCAL_C void doMain()
       
  1089 	{
       
  1090 	TheTest.Start(_L("Predicate tests"));
       
  1091 	TRAPD(errCode, TestPredicatesL());
       
  1092 	TEST2(errCode, KErrNone);
       
  1093 
       
  1094 	TheTest.Next(_L("DML execution"));
       
  1095 	TestDataModificationlanguage();
       
  1096 
       
  1097 	TheTest.Next(_L("ORDER BY clause"));
       
  1098 	TRAP(errCode, TestOrderByL());
       
  1099 	TEST2(errCode, KErrNone);
       
  1100 	TheTest.End();
       
  1101 	}
       
  1102 
       
  1103 // Prepare the test directory.
       
  1104 LOCAL_C void setupTestDirectory()
       
  1105     {
       
  1106 	TInt r=TheFs.Connect();
       
  1107 	TEST2(r, KErrNone);
       
  1108 //
       
  1109 	r=TheFs.MkDir(KTestDatabase);
       
  1110 	TEST(r==KErrNone || r==KErrAlreadyExists);
       
  1111 	}
       
  1112 
       
  1113 // Initialise the cleanup stack.
       
  1114 LOCAL_C void setupCleanup()
       
  1115     {
       
  1116 	TheTrapCleanup=CTrapCleanup::New();
       
  1117 	TEST(TheTrapCleanup!=NULL);
       
  1118 	TRAPD(r,\
       
  1119 		{\
       
  1120 		for (TInt i=KTestCleanupStack;i>0;i--)\
       
  1121 			CleanupStack::PushL((TAny*)0);\
       
  1122 		CleanupStack::Pop(KTestCleanupStack);\
       
  1123 		});
       
  1124 	TEST2(r, KErrNone);
       
  1125 	}
       
  1126 
       
  1127 // Test streaming conversions.
       
  1128 GLDEF_C TInt E32Main()
       
  1129     {
       
  1130 	TheTest.Title();
       
  1131 	setupTestDirectory();
       
  1132 	setupCleanup();
       
  1133 	__UHEAP_MARK;
       
  1134 //
       
  1135 	TheTest.Start(_L("Standard database"));
       
  1136 	doMain();
       
  1137 
       
  1138 	// clean up data file used by this test - must be done before call to End() - DEF047652
       
  1139 	::TestCleanup();
       
  1140 	TheTest.End();
       
  1141 //
       
  1142 	__UHEAP_MARKEND;
       
  1143 
       
  1144 
       
  1145 	delete TheTrapCleanup;
       
  1146 	TheTest.Close();
       
  1147 	return 0;
       
  1148     }