/**
@SYMTestCaseID          SYSLIB-SQL-CT-3480
@SYMTestCaseDesc		Test for INC106788 - Cannot set SQLite page_size bigger than 4k (4096).
						The test attempts to create a database with page size 8K, 16K or 32K, which was not
						possible before (the default page size (1K) has been used).
@SYMTestPriority        High
@SYMTestActions			Test for INC106788 - Cannot set SQLite page_size bigger than 4k (4096).
@SYMTestExpectedResults The test should not fail or panic.
@SYMDEF INC106788
*/
void INC106788()
	{
	//Create a database with page size = 8192.
	(void)RSqlDatabase::Delete(KTestDbName);
	_LIT8(KCfgStr1, "page_size = 8192");
	TInt err = TheDb.Create(KTestDbName, &KCfgStr1);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 8192, 8192, KDefaultEncoding);
	TheDb.Close();

	//Create a database with page size = 16384.
	(void)RSqlDatabase::Delete(KTestDbName);
	_LIT8(KCfgStr2, "page_size = 16384");
	err = TheDb.Create(KTestDbName, &KCfgStr2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 16384, 16384, KDefaultEncoding);
	TheDb.Close();
	
	//Create a database with page size = 32768.
	(void)RSqlDatabase::Delete(KTestDbName);
	_LIT8(KCfgStr3, "page_size = 32768");
	err = TheDb.Create(KTestDbName, &KCfgStr3);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 32768, 32768, KDefaultEncoding);
	TheDb.Close();
	
	(void)RSqlDatabase::Delete(KTestDbName);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3508
@SYMTestCaseDesc		Test for DEF109100: SQL, code coverage for TSqlDbSysSettings is low.
						The test attempts to create a secure shared database with a security policy
						specified for the system tables, which is not allowed.
@SYMTestPriority		High
@SYMTestActions			Test for DEF109100: SQL, code coverage for TSqlDbSysSettings is low.
@SYMTestExpectedResults Test must not fail
@SYMDEF					DEF109100
*/
void StoreSysTableSecurityPolicyTest()
{
    _LIT(KSecurityTable, "symbian_security");
    _LIT(KSettingsTable, "symbian_settings");

    //Case 1: "symbian_security" table
    RSqlSecurityPolicy sp;
    TInt err = sp.Create(KDefaultPolicy);
    TEST2(err, KErrNone);
    err = sp.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, KPolicy1);
    TEST2(err, KErrNone);
    err = sp.SetPolicy(RSqlSecurityPolicy::ETable, KSecurityTable, RSqlSecurityPolicy::EReadPolicy, KPolicy1);
    TEST2(err, KErrNone);
    (void)RSqlDatabase::Delete(KTestDbName);
    RSqlDatabase db;
    err = db.Create(KTestDbName, sp);
    TEST2(err, KErrArgument);
    sp.Close();

    //Case 2: "symbian_settings" table
    err = sp.Create(KDefaultPolicy);
    TEST2(err, KErrNone);
    err = sp.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, KPolicy1);
    TEST2(err, KErrNone);
    err = sp.SetPolicy(RSqlSecurityPolicy::ETable, KSettingsTable, RSqlSecurityPolicy::EReadPolicy, KPolicy1);
    TEST2(err, KErrNone);
    err = RSqlDatabase::Delete(KTestDbName);
    TEST2(err, KErrNotFound);
    err = db.Create(KTestDbName, sp);
    TEST2(err, KErrArgument);
    sp.Close();

    err = RSqlDatabase::Delete(KTestDbName);
    TEST2(err, KErrNotFound);
}
/**
@SYMTestCaseID          PDS-SQL-UT-4152
@SYMTestCaseDesc		Test for DEF142305 - RSqlDatabase::Attach does not use cache_size configuration parameters.
						The test verifies that when a database is attached, the attached database cache size will be set
						based on the page size, soft heap limit and default cache size.
@SYMTestPriority        High
@SYMTestActions			Test for DEF142305 - RSqlDatabase::Attach does not use cache_size configuration parameters.
@SYMTestExpectedResults The test must not fail.
@SYMDEF INC106788
*/
void DEF142305()
	{
	_LIT8(KConfig, "cache_size=500");
	
	//Create main db
	TInt err = TheDb.Create(KTestDbName, &KConfig);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 500, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	
	//Create non-secure db that will be attached 
	err = TheDb.Create(KTestDbName2, &KConfig);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 500, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();

	//Create private db that will be attached 
	_LIT8(KConfig2, "page_size=2048");
	err = TheDb.Create(KTestDbName4, &KConfig2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 2048, 2048, KDefaultEncoding);//2048? - see KConfig2 string
	TheDb.Close();

	_LIT(KAttachDbName, "Attached");
	
	//Attach non-secure db
	err = TheDb.Open(KTestDbName, &KConfig);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 500, KDefaultPageSize, KDefaultEncoding);
	err = TheDb.Attach(KTestDbName2, KAttachDbName);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding, KAttachDbName);
	err = TheDb.Detach(KAttachDbName);
	TEST2(err, KErrNone);
	TheDb.Close();
	
	//Attach private db
	err = TheDb.Open(KTestDbName, &KConfig);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 500, KDefaultPageSize, KDefaultEncoding);
	err = TheDb.Attach(KTestDbName4, KAttachDbName);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 2048, 2048, KDefaultEncoding, KAttachDbName);//2048? - see KConfig2 string
	err = TheDb.Detach(KAttachDbName);
	TEST2(err, KErrNone);
	TheDb.Close();
	
	(void)RSqlDatabase::Delete(KTestDbName4);
	(void)RSqlDatabase::Delete(KTestDbName2);
	(void)RSqlDatabase::Delete(KTestDbName);
	}
void CreateDatabaseL(const TDesC& aDbName)
	{			
	// create the database now
	RSqlSecurityPolicy securityPolicy;
	CleanupClosePushL(securityPolicy);
	
	TSecurityPolicy policy(TSecurityPolicy::EAlwaysPass);
	securityPolicy.Create(policy);
	
	TSecurityPolicy schemaPolicy(TSecurityPolicy::EAlwaysPass);
	TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
	TSecurityPolicy writePolicy(TSecurityPolicy::EAlwaysPass);
	
	User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, schemaPolicy));
	User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, readPolicy));
	User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, writePolicy));
 
	TheTest.Printf(_L("Creating Database %S\n"),  &aDbName);
		
	TInt err = TheDbC.Create(aDbName, securityPolicy, &TheSqlConfigString);

	if (KErrAlreadyExists == err)
		{
		
		// the file already exists
		// make sure we delete the file
        User::LeaveIfError(TheDbC.Delete(aDbName));

        // try again
        err = TheDbC.Create(aDbName, securityPolicy, &TheSqlConfigString);

		}
	
	User::LeaveIfError(err);
	
	//Create tables	
	User::LeaveIfError(TheDbC.Exec(KMusicCreateTable));
	User::LeaveIfError(TheDbC.Exec(KAuxiliaryCreateTable));
	User::LeaveIfError(TheDbC.Exec(KAlbumCreateTable));
	User::LeaveIfError(TheDbC.Exec(KArtistCreateTable));
	User::LeaveIfError(TheDbC.Exec(KComposerCreateTable));
	User::LeaveIfError(TheDbC.Exec(KGenreCreateTable));
	User::LeaveIfError(TheDbC.Exec(KPlaylistCreateTable));
	User::LeaveIfError(TheDbC.Exec(KPlaylistSongInfoCreateTable));
	User::LeaveIfError(TheDbC.Exec(KPlaylistSongsCreateTable));
	
	TheDbC.Close();
	
	CleanupStack::PopAndDestroy(&securityPolicy);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4061
@SYMTestCaseDesc		Secure shared database and compaction configuration test.
						The test verifies that a secure shared database can be created using auto, background or 
						manual compaction mode and that the compaction mode does not chage after reopening 
						the database.
@SYMTestPriority		Medium
@SYMTestActions			Secure shared database and compaction configuration test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10273
                        REQ10274
                        REQ10400
                        REQ10402
*/
void CompactConfigTest6L()
	{
	//Create a secure test database with "auto" compaction mode.
	RSqlSecurityPolicy securityPolicy = CreateTestSecurityPolicy();
	_LIT8(KConfigStr1, "encoding=utf-8;compaction=auto");
	TInt err = TheDb.Create(KTestSecureDbName, securityPolicy, &KConfigStr1);
	TEST2(err, KErrNone);
	securityPolicy.Close();
	TheDb.Close();
	//Check the vacuum mode. The SQLite vacuum mode should be "auto"
	TestCompactMode(KAutoVacuum);
	//Close and open the database again. The SQLite vacuum mode should be "auto".
	err = TheDb.Open(KTestSecureDbName);
	TEST2(err, KErrNone);
	TheDb.Close();
	TestCompactMode(KAutoVacuum);
	//Close and open the database again with a config string with "background" compaction mode. 
	//The SQLite vacuum mode should stay unchanged.
	_LIT8(KConfigStr2, "compaction=background");
	err = TheDb.Open(KTestSecureDbName, &KConfigStr2);
	TEST2(err, KErrNone);
	TheDb.Close();
	TestCompactMode(KAutoVacuum);
	//Delete database
	err = RSqlDatabase::Delete(KTestSecureDbName);
	TEST2(err, KErrNone);
	//Create a private test database - no config string
	securityPolicy = CreateTestSecurityPolicy();
	err = TheDb.Create(KTestSecureDbName, securityPolicy);
	TEST2(err, KErrNone);
	securityPolicy.Close();
	TheDb.Close();
	//Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum.
	TestCompactMode(KSqlDefaultVacuum);
	//Close and open the database again. The SQLite vacuum mode should be KSqlDefaultVacuum.
	err = TheDb.Open(KTestSecureDbName);
	TEST2(err, KErrNone);
	TheDb.Close();
	TestCompactMode(KSqlDefaultVacuum);
	//Close and open the database again with a config string with "auto" compaction mode. 
	//The SQLite vacuum mode should stay unchanged.
	err = TheDb.Open(KTestSecureDbName, &KConfigStr1);
	TEST2(err, KErrNone);
	TheDb.Close();
	TestCompactMode(KSqlDefaultVacuum);
	//Delete database
	err = RSqlDatabase::Delete(KTestSecureDbName);
	TEST2(err, KErrNone);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4058
@SYMTestCaseDesc		Background compaction - configuration test.
						The test creates a database with a background compaction mode.
						The test reopens the database and verifies that the compaction mode is persistent and is still background.
						Then the test reopens the database using different compaction mode in the configuration string and 
						verifies that the original (background) compaction mode cannot be changed when the database is opened.
@SYMTestPriority		Medium
@SYMTestActions			Background compaction - configuration test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10274
*/
void CompactConfigTest3L()
	{
	//Create a test database with "background" compaction mode
	_LIT8(KConfigStr1, "encoding=utf-8;compaction=background");
	TInt err = TheDb.Create(KTestDbName1, &KConfigStr1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "incremental"
	TSqlScalarFullSelectQuery scalarQuery(TheDb);
	TInt compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	TheDb.Close();
	//Close and open the database again. The SQLite vacuum mode should be "incremental".
	err = TheDb.Open(KTestDbName1);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	TheDb.Close();
	//Close and open the database again with a config string with "manual" compaction mode. 
	//The SQLite vacuum mode should stay unchanged.
	_LIT8(KConfigStr2, "compaction=manual");
	err = TheDb.Open(KTestDbName1, &KConfigStr2);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4063
@SYMTestCaseDesc		Compaction configuration test - attached database.
						The test creates a database with an auto compaction mode.
						Then the test attaches the same database.
						The test verifies that the compaction mode of the main and the attached database is the same - auto.
@SYMTestPriority		Medium
@SYMTestActions			Compaction configuration test - attached database.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10273
                        REQ10274
                        REQ10400
*/
void CompactConfigTest8L()
	{
	//Create a test database with "auto" compaction mode
	_LIT8(KConfigStr1, "; ;; ; compaction  =   auto; ");
	TInt err = TheDb.Create(KTestDbName1, &KConfigStr1);
	TEST2(err, KErrNone);
	//Attach a database
	err = TheDb.Attach(KTestDbName1, _L("db2"));
	TEST2(err, KErrNone);
	//Check compact for both main and attached database
	TSqlScalarFullSelectQuery scalarQuery(TheDb);
	TInt compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	compact = scalarQuery.SelectIntL(_L("PRAGMA db2.auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	//Detach
	err = TheDb.Detach(_L("db2"));
	TEST2(err, KErrNone);
	//Check compact again
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	//
	TheDb.Close();
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-CT-1637
@SYMTestCaseDesc		RSqlDatabase::Create() test.
						Tests RSqlDatabase::Create() call when the request is for creation of a secure database.
@SYMTestPriority		High
@SYMTestActions			RSqlDatabase::Create() test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ5792
                        REQ5793
*/
void CreateSecureDatabaseTest()
{
    RSqlSecurityPolicy securityPolicy;

    //Create and initialize RSqlSecurityPolicy object.
    CreateTestSecurityPolicy(securityPolicy);

    //Create secure database using the data from securityPolicy object.
    RSqlDatabase db;
    TInt err = db.Create(KTestDbName, securityPolicy);
    TEST2(err, KErrNone);
    securityPolicy.Close();

    //Check that the database security policy matches the policy used when the database was created.
    err = db.GetSecurityPolicy(securityPolicy);
    TEST2(err, KErrNone);
    CheckTestSecurityPolicy(securityPolicy);
    securityPolicy.Close();

    db.Close();

    //Reopen the database and check the security policies
    err = db.Open(KTestDbName);
    TEST2(err, KErrNone);

    //Check that the database security policy matches the policy used when the database was created.
    err = db.GetSecurityPolicy(securityPolicy);
    TEST2(err, KErrNone);
    CheckTestSecurityPolicy(securityPolicy);
    securityPolicy.Close();

    db.Close();

    err = RSqlDatabase::Delete(KTestDbName);
    TEST2(err, KErrNone);

    //An attempt to create a secure database specifying the full database path
    CreateTestSecurityPolicy(securityPolicy);
    err = db.Create(KTestDbName2, securityPolicy);
    securityPolicy.Close();
    TEST2(err, KErrArgument);

    //An attempt to create a non-secure database formatting the database file name as <drive:><dbFileName>
    err = db.Create(KTestDbName);
    TEST2(err, KErrArgument);
}
/**
Creates a non secure database, which has a table with two integers, and closes it. 
It is deleted at a later point of time after the copy operation.
@leave KErrNotFound, KErrAbort, KErrPermissionDenied,
KErrArgument, system-wide error codes.
*/
void CSqlExample::CreateNonSecureDBL()
	{
	TBuf<200> buffer;
	RSqlDatabase db;
		
	// Create non-secure database
	iConsole->Printf(KNonSecure);
	TInt error;
	TRAP(error,db.Create(KDbName););
/**
@SYMTestCaseID			SYSLIB-SQL-CT-1643
@SYMTestCaseDesc		SQL server private path in database file name test.
						Verify that SQL API returns appropriate error, if an attempt is made to create, open
						or delete a secure database, with the full path specified in the database file name.
@SYMTestPriority		High
@SYMTestActions			SQL server private path in database file name test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ5792
                        REQ5793
*/
void PrivatePathTest()
{
    RSqlSecurityPolicy securityPolicy;
    CreateTestSecurityPolicy(securityPolicy);

    RSqlDatabase db;

    TInt err = db.Create(_L("C:\\PrIVATE\\10281E17\\[98765432]A.DB"), securityPolicy);
    TEST2(err, KErrArgument);
    err = db.Create(_L("C:\\PRIVATE\\10281E17\\[98765432]A.DB"));
    TEST2(err, KErrArgument);
    err = db.Open(_L("C:\\PRIVATE\\10281E17\\[98765432]A.DB"));
    TEST2(err, KErrArgument);
    err = db.Open(_L("C:\\PRIvaTe\\10281E17\\[98765432]A.DB"));
    TEST2(err, KErrArgument);

    err = db.Create(KTestDbName2);
    TEST2(err, KErrNone);
    err = db.Attach(_L("C:\\PRIVATe\\10281E17\\[98765432]A.DB"), _L("Db"));
    TEST2(err, KErrArgument);
    err = db.Attach(_L("C:\\PRIVAtE\\10281E17\\[98765432]A.DB"), _L("Db"));
    TEST2(err, KErrArgument);
    //This is an attempt to attach a database from the application's private data cage
    err = db.Attach(KTestDbName4, _L("Db"));
    TEST2(err, KErrNotFound);//There is no "Db" database file in the application's private data cage
    db.Close();

    err = RSqlDatabase::Delete(_L("C:\\pRIVATE\\10281E17\\[98765432]A.DB"));
    TEST2(err, KErrArgument);
    err = RSqlDatabase::Delete(_L("C:\\PRIvATE\\10281E17\\[98765432]A.DB"));
    TEST2(err, KErrArgument);

    //This is an attempt to create a database in the application's private data cage
    err = db.Create(KTestDbName4);
    TEST2(err, KErrNone);
    db.Close();
    err = RSqlDatabase::Delete(KTestDbName4);
    TEST2(err, KErrNone);

    err = db.Create(KTestDbName5);
    TEST2(err, KErrArgument);

    securityPolicy.Close();
}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4049
@SYMTestCaseDesc		Database configuration string - injection test.
						The test attempts to create a database using a configuration string
						and passing a DELETE SQL statement as a compaction mode name.
						The database should be created successfully, the invalid compaction mode - ignored,
						the database system tables content shoud not be corrupted by the call.
@SYMTestPriority		High
@SYMTestActions			Database configuration string - injection test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10405
*/
void InjectionTest()
	{
	(void)RSqlDatabase::Delete(KTestDbName);
	TInt err = TheDb.Create(KTestDbName);
	TEST2(err, KErrNone);
	err = TheDb.Exec(_L("CREATE TABLE A(I INTEGER); INSERT INTO A(I) VALUES(1);"));
	TEST(err > 0);
	TheDb.Close();
	
	_LIT8(KConfig1, "cache_size=128;DELETE FROM A");
	err = TheDb.Open(KTestDbName, &KConfig1);
	TEST2(err, KErrArgument);
	err = TheDb.Open(KTestDbName);
	TEST2(err, KErrNone);
	TSqlScalarFullSelectQuery query(TheDb);
	TInt recCount = 0;
	TRAP(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM A")));
	TEST2(err, KErrNone);
	TEST2(recCount, 1);
	TheDb.Close();

	_LIT8(KConfig2, "cache_size=256;compaction=DELETE FROM A;");
	err = TheDb.Open(KTestDbName, &KConfig2);
	TEST2(err, KErrNone);
	query.SetDatabase(TheDb);
	recCount = 0;
	TRAP(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM A")));
	TEST2(err, KErrNone);
	TEST2(recCount, 1);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);

	_LIT8(KConfig3, "cache_size=256;compaction=DELETE FROM symbian_settings;");
	err = TheDb.Create(KTestDbName, &KConfig3);
	TEST2(err, KErrNone);
	query.SetDatabase(TheDb);
	recCount = 0;
	TRAP(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings")));
	TEST2(err, KErrNone);
	TEST2(recCount, 1);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	}
//This functnion is called while there is an open secure connection.
//The function will create a new, non-secure connection and check that the non-secure database schema can be modified,
//while there is another alive, secure database connection.
void NonSecureDbTest()
    {
    (void)RSqlDatabase::Delete(KTestDbName2);
    RSqlDatabase db;
    TInt err = db.Create(KTestDbName2);
    TEST2(err, KErrNone);
    
    err = db.Exec(_L("CREATE TABLE A(I1 INTEGER, I2 INTEGER)"));
    TEST(err >= 0);
    err = db.Exec(_L("CREATE TEMP TABLE B(I1 INTEGER, I2 INTEGER)"));
    TEST(err >= 0);

    //"CREATE VIRTUAL TABLE" statement not supported
    err = db.Exec(_L("CREATE VIRTUAL TABLE V1 USING FTS3(ColOne TEXT, ColTwo DATETIME)"));
    TPtrC msg = db.LastErrorMessage();
    TheTest.Printf(_L("*** \"CREATE VIRTUAL TABLE\" expected failure, msg=\"%S\", err=%d\r\n"), &msg, err);
    TEST(err != KErrNone);
    
    err = db.Exec(_L("CREATE TRIGGER T1 AFTER INSERT ON A BEGIN INSERT INTO B VALUES(new.I1, new.I2); END;"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP TRIGGER T1"));
    TEST(err >= 0);
    err = db.Exec(_L("CREATE TEMP TRIGGER T2 AFTER UPDATE OF I1 ON A BEGIN UPDATE B SET I1 = new.I1; END;"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP TRIGGER T2"));
    TEST(err >= 0);

    err = db.Exec(_L("CREATE VIEW V1 AS SELECT * FROM A"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP VIEW V1"));
    TEST(err >= 0);
    err = db.Exec(_L("CREATE TEMP VIEW V2 AS SELECT * FROM A"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP VIEW V2"));
    TEST(err >= 0);

    err = db.Exec(_L("CREATE INDEX Idx1 ON A(I1)"));
    TEST(err >= 0);
    err = db.Exec(_L("ANALYZE A"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP INDEX Idx1"));
    TEST(err >= 0);
    err = db.Exec(_L("CREATE INDEX Idx2 ON B(I1)"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP INDEX Idx2"));
    TEST(err >= 0);
        
    err = db.Exec(_L("DROP TABLE B"));
    TEST(err >= 0);
    err = db.Exec(_L("DROP TABLE A"));
    TEST(err >= 0);
    
    db.Close();
    (void)RSqlDatabase::Delete(KTestDbName2);
    }
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3439
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test creates two databases using configuration strings and checks that database 1
						configuration has no impact on database 2 configuration.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgCrossConnectionTest()
	{
	//Create database 1 with cache size = 40, page size = 2048.
	_LIT8(KCfgStr1, "cache_size = 40; page_size = 2048");
	TInt err = TheDb.Create(KTestDbName, &KCfgStr1);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 40, 2048, KDefaultEncoding);
	//Without closing database 1, create database 2 without a configuration string.
	//Check that database 2 uses the default configuration parameters
	err = TheDb2.Create(KTestDbName2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb2, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	//Close database 2. Check the configuration parameters of database 1
	TheDb2.Close();
	AssertConfigPrmValues(TheDb, 40, 2048, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName2);
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create 2 databases with different configuration parameters
	_LIT8(KCfgStr2_1, "cache_size = 50; page_size = 512; encoding = \"UTF-16\"");
	_LIT8(KCfgStr2_2, "cache_size = 80; page_size = 4096; encoding = \"UTF-8\"");
	err = TheDb.Create(KTestDbName, &KCfgStr2_1);
	TEST2(err, KErrNone);
	err = TheDb2.Create(KTestDbName2, &KCfgStr2_2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 50, 512, TSqlSrvConfigParams::EEncUtf16);
	AssertConfigPrmValues(TheDb2, 80, 4096, TSqlSrvConfigParams::EEncUtf8);
	TheDb2.Close();
	TheDb.Close();
	//Reopen the databases and check the configuration parameters
	err = TheDb.Open(KTestDbName);
	TEST2(err, KErrNone);
	err = TheDb2.Open(KTestDbName2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 512, 512, TSqlSrvConfigParams::EEncUtf16);
	AssertConfigPrmValues(TheDb2, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 4096, 4096, TSqlSrvConfigParams::EEncUtf8);
	TheDb2.Close();
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName2);
	(void)RSqlDatabase::Delete(KTestDbName);
	}
static void CreateTestDatabase()
	{
	RSqlDatabase::Delete(KTestDbName);

	_LIT8(KConfigStr, "encoding=\"UTF-8\"");
	TInt err = TheDb.Create(KTestDbName, &KConfigStr);
	TEST2(err, KErrNone);

	err = TheDb.Exec(_L8("CREATE TABLE Tbl(I INTEGER PRIMARY KEY, I64 BIGINT, D DOUBLE, T TEXT, B BINARY)"));
	TEST2(err, 1);

	TheDb.Close();
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4059
@SYMTestCaseDesc		Background compaction - no configuration string test.
						The test creates a database without using a configuration string.
						The database should be created with default compaction mode - background.
						The test reopens the database and verifies that the compaction mode is persistent and is still background.
						Then the test reopens the database using different compaction mode in the configuration string and 
						verifies that the original (background) compaction mode cannot be changed when the database is opened.
@SYMTestPriority		Medium
@SYMTestActions			Background compaction - no configuration string test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10273
                        REQ10274
*/
void CompactConfigTest4L()
	{
	//Create a test database without configuration string
	TInt err = TheDb.Create(KTestDbName1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum
	TSqlScalarFullSelectQuery scalarQuery(TheDb);
	TInt compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	//Create a test database with invalid configuration string
	_LIT8(KConfigStr1, "encoding=utf-8;compaction=backgrund");
	err = TheDb.Create(KTestDbName1, &KConfigStr1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	//Create a test database with invalid configuration string
	_LIT8(KConfigStr2, "compactin=background");
	err = TheDb.Create(KTestDbName1, &KConfigStr2);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3438
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test attempts to create a database with configuration string containing:
						negative or zero page size and cache size, too small or too big page size,
						page size, not power of two. The test expects the SQL server will detect those 
						invalid page size and cache size values and will refuse to execute the operation.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgInvalidCacheAndPageSizeTest()
	{
	//Create a database. Page size < 512.
	_LIT8(KCfgStr1, "page_size=128;");
	TInt err = TheDb.Create(KTestDbName, &KCfgStr1);
	TEST2(err, KErrNone);//Invalid page size: KErrNone expected, but the page size will not be set
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Page size > 32768.
	_LIT8(KCfgStr2, "page_size=65535;");
	err = TheDb.Create(KTestDbName, &KCfgStr2);
	TEST2(err, KErrNone);//Invalid page size: KErrNone expected, but the page size will not be set
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Page size is not power of two.
	_LIT8(KCfgStr3, "page_size=5000;");
	err = TheDb.Create(KTestDbName, &KCfgStr3);
	TEST2(err, KErrNone);//Invalid page size: KErrNone expected, but the page size will not be set
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Zero cache size.
	_LIT8(KCfgStr4, "cache_size=0");
	err = TheDb.Create(KTestDbName, &KCfgStr4);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 0, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Negative cache size.
	_LIT8(KCfgStr5, "cache_size=-32");
	err = TheDb.Create(KTestDbName, &KCfgStr5);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Zero page size.
	_LIT8(KCfgStr6, "page_size=0");
	err = TheDb.Create(KTestDbName, &KCfgStr6);
	TEST2(err, KErrNone);//Invalid page size: KErrNone expected, but the page size will not be set
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Negative page size.
	_LIT8(KCfgStr7, "page_size=-1024");
	err = TheDb.Create(KTestDbName, &KCfgStr7);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3440
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test creates a secure database with a configuration string. The test must not fail.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgSecureDbTest()
	{
	//Create
	TSecurityPolicy policy(TSecurityPolicy::EAlwaysPass);
	RSqlSecurityPolicy dbPolicy;
	TInt err = dbPolicy.Create(policy);
	TEST2(err, KErrNone);
	_LIT8(KCfgStr1, "cache_size = 80; page_size = 4096; encoding = UTF-8");
	err = TheDb.Create(KTestDbName3, dbPolicy, &KCfgStr1);
	TEST2(err, KErrNone);
	//Since it is a secure database, PRAGMAs cannot be executed (in order to assert the parameter values)
	//AssertConfigPrmValues(TheDb, 80, 4096, TSqlSrvConfig::EEncUtf8);
	TheDb.Close();	
	dbPolicy.Close();
	//Open
	_LIT8(KCfgStr2, "cache_size = 100");
	err = TheDb.Open(KTestDbName3, &KCfgStr2);
	TEST2(err, KErrNone);
	TheDb.Close();	
	(void)RSqlDatabase::Delete(KTestDbName3);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3441
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test creates a private database with a configuration string. The test must not fail.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgPrivateDbTest()
	{
	//Create
	_LIT8(KCfgStr1, "cache_size = 80; page_size = 4096; encoding = UTF-8");
	TInt err = TheDb.Create(KTestDbName4, &KCfgStr1);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 80, 4096, TSqlSrvConfigParams::EEncUtf8);
	TheDb.Close();	
	//Open-1. The cache size can be changed.
	_LIT8(KCfgStr2, "cache_size = 100");
	err = TheDb.Open(KTestDbName4, &KCfgStr2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 100, 4096, TSqlSrvConfigParams::EEncUtf8);
	TheDb.Close();	
	//Open-2. The page size cannot be changed if the database does exist already.
	_LIT8(KCfgStr3, "page_size = 512");
	err = TheDb.Open(KTestDbName4, &KCfgStr3);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 4096, 4096, TSqlSrvConfigParams::EEncUtf8);
	TheDb.Close();	
	(void)RSqlDatabase::Delete(KTestDbName4);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3436
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test attempts to create/open a database using different cache size/page size/
						database encoding configurations and then checks that the configuration parameters
						have been set properly and have the expected values.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgFunctionalTest()
	{
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. No config string. The default config parameters will be used.
	TInt err = TheDb.Create(KTestDbName);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Cache size set.
	_LIT8(KCfgStr1, "cache_size=32");
	err = TheDb.Create(KTestDbName, &KCfgStr1);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 32, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Page size set.
	_LIT8(KCfgStr2, "page_size=2048");
	err = TheDb.Create(KTestDbName, &KCfgStr2);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 2048, 2048, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Cache & Page size set.
	_LIT8(KCfgStr3, "cache_size=256;page_size=4096");
	err = TheDb.Create(KTestDbName, &KCfgStr3);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 256, 4096, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Cache size & Page size & db encoding set.
	_LIT8(KCfgStr4, "cache_size=512;page_size=512;encoding=UTF-8");
	err = TheDb.Create(KTestDbName, &KCfgStr4);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 512, 512, TSqlSrvConfigParams::EEncUtf8);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Cache size & Page size & db encoding set.
	_LIT8(KCfgStr5, "cache_size=16;page_size=1024;encoding=UTF-16");
	err = TheDb.Create(KTestDbName, &KCfgStr5);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 16, 1024, TSqlSrvConfigParams::EEncUtf16);
	TheDb.Close();
	//Open the database. Cache size set. The rest of parameter values must be the same as for KCfgStr5.
	_LIT8(KCfgStr6, "cache_size=80");
	err = TheDb.Open(KTestDbName, &KCfgStr6);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, 80, 1024, TSqlSrvConfigParams::EEncUtf16);
	TheDb.Close();
	//Open the database. Attempt to set the page size (impossible when opening a database).
	_LIT8(KCfgStr7, "page_size=2048");
	err = TheDb.Open(KTestDbName, &KCfgStr7);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, 1024, TSqlSrvConfigParams::EEncUtf16);
	TheDb.Close();
	//Open the database. Attempt to set the encoding (impossible when opening a database).
	_LIT8(KCfgStr8, "encoding=UTF-8");
	err = TheDb.Open(KTestDbName, &KCfgStr8);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, 1024, TSqlSrvConfigParams::EEncUtf16);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Empty config string - 1
	_LIT8(KCfgStr9, "");
	err = TheDb.Create(KTestDbName, &KCfgStr9);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Empty config string - 2
	_LIT8(KCfgStr10, "       ");
	err = TheDb.Create(KTestDbName, &KCfgStr10);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Empty config string - 3
	_LIT8(KCfgStr11, " ; ;   ;;   ");
	err = TheDb.Create(KTestDbName, &KCfgStr11);
	TEST2(err, KErrNone);
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4060
@SYMTestCaseDesc		Private database and compaction configuration test.
						The test verifies that a private database can be created using auto, background or 
						manual compaction mode and that the compaction mode does not chage after reopening 
						the database.
						The test also verifies that if the database is legacy, read-only, then the compaction
						mode is auto.
						The test also verifies that if the database is legacy, r/w, then the compaction
						mode will be changed from auto to background.
@SYMTestPriority		Medium
@SYMTestActions			Private database and compaction configuration test.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10273
                        REQ10274
                        REQ10400
                        REQ10402
*/
void CompactConfigTest5L()
	{
	//Create a private test database with "auto" compaction mode
	_LIT8(KConfigStr1, "encoding=utf-8;compaction=auto");
	TInt err = TheDb.Create(KTestPrivDbName, &KConfigStr1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "auto"
	TSqlScalarFullSelectQuery scalarQuery(TheDb);
	TInt compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TheDb.Close();
	//Close and open the database again. The SQLite vacuum mode should be "auto".
	err = TheDb.Open(KTestPrivDbName);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TheDb.Close();
	//Close and open the database again with a config string with "background" compaction mode. 
	//The SQLite vacuum mode should stay unchanged.
	_LIT8(KConfigStr2, "compaction=background");
	err = TheDb.Open(KTestPrivDbName, &KConfigStr2);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestPrivDbName);
	TEST2(err, KErrNone);
	//Create a private test database - no config string
	err = TheDb.Create(KTestPrivDbName);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Close and open the database again. The SQLite vacuum mode should be KSqlDefaultVacuum.
	err = TheDb.Open(KTestPrivDbName);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Close and open the database again with a config string with "auto" compaction mode. 
	//The SQLite vacuum mode should stay unchanged.
	err = TheDb.Open(KTestPrivDbName, &KConfigStr1);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	//Delete database
	err = RSqlDatabase::Delete(KTestPrivDbName);
	TEST2(err, KErrNone);
	//Open an existing private database that is read-only (on drive Z:)
	err = TheDb.Open(KTestPrivDbNameZ, &KConfigStr1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite compact mode should be "auto" (this is an old database (pre-"background compact" era))
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TheDb.Close();
	//Open the same database after copying it to drive C: (r/w private database). The compaction mode should change from auto to background.
	RFs fs;
	err = fs.Connect();
	TEST2(err, KErrNone);
	CFileMan* fm = CFileMan::NewL(fs);
	TEST(fm != NULL);
	err = fm->Copy(KTestPrivDbNameZ, KTestPrivDbNameC);
	TEST2(err, KErrNone);
	//"Copy" operation executed without errors. Now it is a time to turn off the read-only
	//flag of the target file (which may be on if the source file is on a read-only drive)
	err = fs.SetAtt(KTestPrivDbNameC, 0, KEntryAttReadOnly);
	TEST2(err, KErrNone);
	delete fm;
	fs.Close();
	err = TheDb.Open(KTestPrivDbNameC);
	TEST2(err, KErrNone);
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KSqlDefaultVacuum);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestPrivDbNameC);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-3437
@SYMTestCaseDesc		Test for DEF105928 "SQL server ignores config string parameters".
						The test attempts to create/open a database using invalid configuration strings,
						too long configuration string, string with missing parameter values, string with
						invalid database encodings. The test expects the SQL server will report a failure
						and will refuse to execute the operation.
@SYMTestPriority		High
@SYMTestActions			Test for DEF105928 "SQL server ignores config string parameters".
@SYMTestExpectedResults The test must not fail
@SYMDEF					DEF105928
*/
void CfgNegativeTest()
	{
	//Create a database. Spelling problem in the parameter name. This is not reported as an error by the SQL server
	//(treated as unknown parameter)
	_LIT8(KCfgStr1, "casche_size = 32");
	TInt err = TheDb.Create(KTestDbName, &KCfgStr1);
	TEST2(err, KErrNone);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Spelling problem in the parameter value. 
	_LIT8(KCfgStr2, "encoding = UTF-32");
	err = TheDb.Create(KTestDbName, &KCfgStr2);
	TEST2(err, KErrNone);//Invalid encoding: KErrNone, but the encoding will not be used
	AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Invalid config string.
	_LIT8(KCfgStr3, "dfgjkdfgkdfk; sfkgjhdfgjkdfk; dfgdfetrwer");
	err = TheDb.Create(KTestDbName, &KCfgStr3);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Too long and invalid config string.
	_LIT8(KCfgStr4, "A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789");
	err = TheDb.Create(KTestDbName, &KCfgStr4);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. No parameter value - 1.
	_LIT8(KCfgStr5, "page_size=");
	err = TheDb.Create(KTestDbName, &KCfgStr5);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. No parameter value - 2.
	_LIT8(KCfgStr6, "page_size=;");
	err = TheDb.Create(KTestDbName, &KCfgStr6);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Non-number parameter value - 1.
	_LIT8(KCfgStr7, "page_size=aaa;");
	err = TheDb.Create(KTestDbName, &KCfgStr7);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. Non-number parameter value - 2.
	_LIT8(KCfgStr8, "cache_size=weyu34;");
	err = TheDb.Create(KTestDbName, &KCfgStr8);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. "soft_heap_limit_kb" in the config string.
	_LIT8(KCfgStr9, "soft_heap_limit_kb=512;");
	err = TheDb.Create(KTestDbName, &KCfgStr9);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	//Create a database. "free_space_threshold_kb" in the config string.
	_LIT8(KCfgStr10, "free_space_threshold_kb=256;");
	err = TheDb.Create(KTestDbName, &KCfgStr10);
	TEST2(err, KErrArgument);
	TheDb.Close();
	(void)RSqlDatabase::Delete(KTestDbName);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-CT-1614
@SYMTestCaseDesc		Verifying that when having 2 database connections in different threads, both set
						the isolation level to "Read Uncommitted", the reading thread can make "dirty read"
						operations (can read the updated but not committed yet record values made by the
						writing thread).
@SYMTestPriority		High
@SYMTestActions			Testing "Read Uncommitted" database isolation level.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ5792
                        REQ5793
*/	
void TestIsolationLevel()
	{
	RDebug::Print(_L("+++:MainThread: Create critical sections\r\n"));
	TEST2(UpdateThreadCrS.CreateLocal(), KErrNone);
	UpdateThreadCrS.Wait();
	TEST2(MainThreadCrS.CreateLocal(), KErrNone);
	MainThreadCrS.Wait();
	
	RDebug::Print(_L("+++:MainThread: Create test database\r\n"));
	RSqlDatabase db;
	TInt err = db.Create(KTestDbName1);
	TEST2(err, KErrNone);

	RDebug::Print(_L("+++:MainThread: Set the isolation level to \"Read uncommitted\"\r\n"));
	err = db.SetIsolationLevel(RSqlDatabase::EReadUncommitted);
	TEST2(err, KErrNone);
	
	RDebug::Print(_L("+++:MainThread: Create a table in the test database\r\n"));
	_LIT8(KCreateSql, "CREATE TABLE A(Id INTEGER)");
	err = db.Exec(KCreateSql);
	TEST(err >= 0);

	RDebug::Print(_L("+++:MainThread: Insert one record in the table\r\n"));
	_LIT8(KInsertSql, "INSERT INTO A(Id) VALUES(");
	TBuf8<64> sql(KInsertSql);
	sql.AppendNum((TInt64)KInitialValue);
	sql.Append(_L(")"));
	err = db.Exec(sql);
	TEST2(err, 1);

	RDebug::Print(_L("+++:MainThread: Create the \"update\" thread\r\n"));
	_LIT(KThreadName, "UpdTh");
	RThread thread;
	TEST2(thread.Create(KThreadName, &UpdateThreadFunc, 0x2000, 0x1000, 0x10000, NULL, EOwnerThread), KErrNone);
	TRequestStatus status;
	thread.Logon(status);
	TEST2(status.Int(), KRequestPending);
	thread.Resume();

	RDebug::Print(_L("+++:MainThread: Wait for record update completion...\r\n"));
	MainThreadCrS.Wait();

	RDebug::Print(_L("+++:MainThread: Read the record and check the data...\r\n"));
	_LIT8(KSelectSql, "SELECT * FROM A");
	RSqlStatement stmt;
	err = stmt.Prepare(db, KSelectSql);
	TEST2(err, KErrNone);
	err = stmt.Next();
	TEST2(err, KSqlAtRow);
	TInt val = stmt.ColumnInt(0);
	TEST(val == KUpdatedValue);
	stmt.Close();

	RDebug::Print(_L("+++:MainThread: Notify the update thread that it can rollback\r\n"));
	UpdateThreadCrS.Signal();

	RDebug::Print(_L("+++:MainThread: Wait for  rollback  completion...\r\n"));
	MainThreadCrS.Wait();

	RDebug::Print(_L("+++:MainThread: Read the record and check the data...\r\n"));
	err = stmt.Prepare(db, KSelectSql);
	TEST2(err, KErrNone);
	err = stmt.Next();
	TEST2(err, KSqlAtRow);
	val = stmt.ColumnInt(0);
	TEST2(val, KInitialValue);
	stmt.Close();

	User::WaitForRequest(status);
	thread.Close();

	db.Close();
	RDebug::Print(_L("+++:MainThread: Delete the test database\r\n"));
	(void)RSqlDatabase::Delete(KTestDbName1);

	RDebug::Print(_L("+++:MainThread: Close critical sections\r\n"));
	MainThreadCrS.Close();
	UpdateThreadCrS.Close();
	}
/**
@SYMTestCaseID			SYSLIB-SQL-CT-1613
@SYMTestCaseDesc		Multiple connections to the same database from different threads. 
						Each thread inserts set of record to the same table. Verify that all expected records
						and their column values meet the expectations.
@SYMTestPriority		High
@SYMTestActions			Testing SQL engine behaviour when having mutiple connections to the same database
						from different threads.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ5792
                        REQ5793
*/	
void TestMultiConnDiffThread()
	{
	//Create a test database
	RDebug::Print(_L("+++:MainThread: Create test database\r\n"));
	RSqlDatabase db;
	TInt err = db.Create(KTestDbName1);
	TEST2(err, KErrNone);
	
	//Create a test table
	RDebug::Print(_L("+++:MainThread: Create a table in the test database\r\n"));
	_LIT8(KCreateSql, "CREATE TABLE A(Id INTEGER PRIMARY KEY)");
	err = db.Exec(KCreateSql);
	TEST(err >= 0);
	
	const TInt KThreadCnt = 4;
	const TInt KRange = 100;
	
	const TInt KIsolationLevelCnt = 2;
	TPtrC KIsolationLevelName[KIsolationLevelCnt] = {_L("Read Uncommitted"), _L("Serializable")};
	const RSqlDatabase::TIsolationLevel KIsolationLevels[KIsolationLevelCnt] = {
											RSqlDatabase::EReadUncommitted, RSqlDatabase::ESerializable};
											
	const TInt KTransTypeCnt = 2;											

	//Do the tests:
	// - doing each per thread database operation in a single transaction;
	// - doing all per thread database operations in a single transaction;
	for(TInt transType=0;transType<KTransTypeCnt;++transType)	
		{
		//For both supported isolation levels: read uncommitted and serializable
		for(TInt isolLevel=0;isolLevel<KIsolationLevelCnt;++isolLevel)
			{
			TInt low = 1;
			TInt high = KRange;
			
			RDebug::Print(_L("+++:MainThread: Test: thread count %d, records %d, trans type %d, isolation level: %S\r\n"), 
									KThreadCnt, KRange, transType, &KIsolationLevelName[isolLevel]);
									
			RThread thread[KThreadCnt];
			TRequestStatus status[KThreadCnt];
			TThreadData	data[KThreadCnt];

			//Create the test threads and run them. Each thread establishes a connection with the test database
			//and attempts to write set of records in the test table.
			TInt j;
			for(j=0;j<KThreadCnt;++j,low=high+1,high+=KRange)
				{
				data[j].iTransType = transType;
				data[j].iIsolationLevel = KIsolationLevels[isolLevel];
				data[j].iLowRecNo = low;
				data[j].iHighRecNo = high;
				
				_LIT(KThreadName,"Thr-");
				TBuf<32> threadName(KThreadName);
				threadName.AppendNum((TInt64)j + 1);
				
				TEST2(thread[j].Create(threadName, &ThreadFunc, 0x2000, 0x1000, 0x10000, (void*)&data[j], EOwnerThread), KErrNone);
				thread[j].Logon(status[j]);
				TEST2(status[j].Int(), KRequestPending);
				thread[j].Resume();
				}
			
			User::After(2000000);
			//Wait until threads finish the database operations and close them.				
			for(j=0;j<KThreadCnt;++j)
				{
				User::WaitForRequest(status[j]);
				TEST(thread[j].ExitType() != EExitPanic);
				thread[j].Close();
				}

			//Check that all records which are esupposed to be in the database, are there.
			RDebug::Print(_L("+++:MainThread: Check that all records have been written\r\n"));
			_LIT8(KSelectSql1, "SELECT COUNT(*) FROM A;");
			RSqlStatement stmt;
			err = stmt.Prepare(db, KSelectSql1);
			TEST2(err, KErrNone);
			err = stmt.Next();
			TEST2(err, KSqlAtRow);
			TInt cnt = stmt.ColumnInt(0);
			TEST2(cnt, KThreadCnt * KRange);
			stmt.Close();
			
			//Check that all records have expected column values.
			RDebug::Print(_L("+++:MainThread: Check that all records have expected column values\r\n"));
			_LIT8(KSelectSql2, "SELECT * FROM A;");
			err = stmt.Prepare(db, KSelectSql2);
			TEST2(err, KErrNone);
			for(TInt k=0;k<(KThreadCnt*KRange);++k)
				{
				err = stmt.Next();
				TEST2(err, KSqlAtRow);
				TInt val = stmt.ColumnInt(0);
				TEST(val > 0 && val <= (KThreadCnt * KRange));
				}
			stmt.Close();

			//Prepare for the next test run - delete all records.
			RDebug::Print(_L("+++:MainThread: Delete all records\r\n"));
			_LIT8(KDeleteSql, "DELETE FROM A");
			err = db.Exec(KDeleteSql);
			TEST(err >= 0);
			}//end of "for(TInt isolLevel=0;isolLevel<KIsolationLevelCnt;++isolLevel)"
		}//end of "for(TInt transType=0;transType<KTransTypeCnt;++transType)"
		
	db.Close();
	RDebug::Print(_L("+++:MainThread: Delete the test database\r\n"));
	(void)RSqlDatabase::Delete(KTestDbName1);
	}
/**
@SYMTestCaseID			SYSLIB-SQL-UT-4062
@SYMTestCaseDesc		Compaction configuration test - multiple connections.
						The test creates a database with auto or background compaction mode.
						Then the test opens more connections to the same database.
						The test verifies that the compaction mode of the connections opened later is
						the same as the compaction mode of the database that was openen first.
						The test also verifies that the compactino mode cannot be changed even if the second
						connection is opened with a configuration string with a specified different compaction mode.
@SYMTestPriority		Medium
@SYMTestActions			Compaction configuration test - multiple connections.
@SYMTestExpectedResults Test must not fail
@SYMREQ					REQ10273
                        REQ10274
                        REQ10400
*/
void CompactConfigTest7L()
	{
	//Create a test database with "auto" compaction mode.
	_LIT8(KConfigStr1, "encoding=utf-8;compaction  =   auto");
	TInt err = TheDb.Create(KTestDbName1, &KConfigStr1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "auto"
	TSqlScalarFullSelectQuery scalarQuery(TheDb);
	TInt compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	//Open a second connection to the same database - no config string
	RSqlDatabase db2;
	err = db2.Open(KTestDbName1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "auto"
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TSqlScalarFullSelectQuery scalarQuery2(db2);
	compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	//Open a third connection to the same database - "background" compaction mode config string
	_LIT8(KConfigStr2, "  encoding =    utf-8 ; ; ; compaction  =   background   ");
	RSqlDatabase db3;
	err = db3.Open(KTestDbName1, &KConfigStr2);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "auto"
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	TSqlScalarFullSelectQuery scalarQuery3(db3);
	compact = scalarQuery3.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KAutoVacuum);
	//Close & Delete database
	db3.Close();
	db2.Close();
	TheDb.Close();
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	//
	//
	//Create a test database with "background" compaction mode
	_LIT8(KConfigStr3, "compaction  =   background   ;;;;");
	err = TheDb.Create(KTestDbName1, &KConfigStr3);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "incremental"
	scalarQuery.SetDatabase(TheDb);
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	//Open a second connection to the same database - no config string
	err = db2.Open(KTestDbName1);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "incremental"
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	scalarQuery2.SetDatabase(db2);
	compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	//Open a third connection to the same database - "auto" compaction mode config string
	_LIT8(KConfigStr4, "  encoding =    utf-16 ; compaction  =   auto   ; ; ; ");
	err = db3.Open(KTestDbName1, &KConfigStr4);
	TEST2(err, KErrNone);
	//Check the vacuum mode. The SQLite vacuum mode should be "incremental"
	compact = scalarQuery.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	scalarQuery3.SetDatabase(db3);
	compact = scalarQuery3.SelectIntL(_L("PRAGMA auto_vacuum"));
	TEST2(compact, KIncrementalVacuum);
	//Close & Delete database
	db3.Close();
	db2.Close();
	TheDb.Close();
	err = RSqlDatabase::Delete(KTestDbName1);
	TEST2(err, KErrNone);
	}