Merge Symbian Foundation splash screen.
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
#include "TzLocalizationDbAccessor.h"
#include "TzLocalizationDataTypes.h"
//==================================================================
// Database location and access policy
//==================================================================
_LIT(KTzLocalizationDbName,"c:TzLocalization.db");
_LIT(KTzLocalizationDbSecurityPolicy,"secure[10206A8B]");
//==================================================================
//==================================================================
//Table and Column names for Cached Time Zone Table
//These text strings are never visible and do not need localizing
//==================================================================
_LIT(KCZTableName, "FrequentlyUsedZones");
_LIT(KCZTableTzIdCol, "TzId");
_LIT(KCZTableStdCol, "StandardName");
_LIT(KCZTableDSTCol, "DSTName");
_LIT(KCZTableShortStdCol, "ShortStandardName");
_LIT(KCZTableShortDSTCol, "ShortDSTName");
_LIT(KCZTableCityCol, "City");
_LIT(KCZTableCityGroupCol, "GroupId");
_LIT(KCZTableResourceIdCol, "ResourceId");
_LIT(KCZTableCityIndexCol, "CityIndex");
//==================================================================
//Table and Column names for User Added Cities Table
//These text strings are never visible and do not need localizing
//==================================================================
_LIT(KUCTableName, "UserCities");
_LIT(KUCTableTzId, "TzId");
_LIT(KUCTableCity, "City");
_LIT(KUCTableGroup, "GroupId");
_LIT(KUCTableResourceId, "ResourceId");
/**
Allocates and constructs a new CTzLocalizationDbAccessor
@return the newly constructed CTzLocalizationDbAccessor
@internalTechnology
*/
CTzLocalizationDbAccessor* CTzLocalizationDbAccessor::NewL()
{
CTzLocalizationDbAccessor* self = CTzLocalizationDbAccessor::NewLC();
CleanupStack::Pop(self);
return self;
}
/**
Allocates and constructs a new CTzLocalizationDbAccessor
The pointer to the new object is left on the cleanup stack
@return the newly constructed CTzLocalizationDbAccessor
@internalTechnology
*/
CTzLocalizationDbAccessor* CTzLocalizationDbAccessor::NewLC()
{
CTzLocalizationDbAccessor* self = new (ELeave) CTzLocalizationDbAccessor();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CTzLocalizationDbAccessor::CTzLocalizationDbAccessor()
{
}
/**
Second phase construction
Connects to a database session and opens the database. If the database doesn't exist it is created
and populated with blank time zone data
@internalTechnology
*/
void CTzLocalizationDbAccessor::ConstructL()
{
OpenDbL();
}
void CTzLocalizationDbAccessor::OpenDbL()
{
if (iZoneMutex.OpenGlobal(KTzMutexName) != KErrNone)
{
User::LeaveIfError(iZoneMutex.CreateGlobal(KTzMutexName)) ;
}
//Connect to database server session
User::LeaveIfError(iDbsSession.Connect());
//Attempt to open the database
TInt error = iLocalizedTimeZoneDb.Open(iDbsSession,KTzLocalizationDbName,KTzLocalizationDbSecurityPolicy);
if (error == KErrNotFound)
{
//Database file doesn't exist. Attempt to create a new one.
error = iLocalizedTimeZoneDb.Create(iDbsSession,KTzLocalizationDbName,KTzLocalizationDbSecurityPolicy);
if (error == KErrNone)
{
User::LeaveIfError(CreateFrequentlyUsedZoneTableL());
User::LeaveIfError(CreateUserCityTableL());
}
}
User::LeaveIfError(error);
// Check if both tables are created.
TRAP(error, iLocalizedTimeZoneDb.ColSetL(KCZTableName));
if (error)
{
User::LeaveIfError(CreateFrequentlyUsedZoneTableL());
}
TRAP(error, iLocalizedTimeZoneDb.ColSetL(KUCTableName));
if (error)
{
User::LeaveIfError(CreateUserCityTableL());
}
}
/**
Destructor
Closes the database tables, the database and the database session
@internalTechnology
*/
CTzLocalizationDbAccessor::~CTzLocalizationDbAccessor()
{
CloseDb();
iDbsSession.Close();
}
void CTzLocalizationDbAccessor::CloseDb()
{
iCityView.Close();
iZoneView.Close();
iLocalizedTimeZoneDb.Close();
if (iZoneMutex.IsHeld()) // it is a leave, so release mutex
{
iZoneMutex.Signal();
}
iZoneMutex.Close();
}
// Close and delete the DB and create a new one in the latest format
void CTzLocalizationDbAccessor::RecreateDbL(RTz& aTzSession)
{
CloseDb();
aTzSession.LocalizationCloseDbL();
const TUid KTzLocalizationDbSecurityPolicyUid = {0x10206A8B};
User::LeaveIfError(iDbsSession.DeleteDatabase(KTzLocalizationDbName(),KTzLocalizationDbSecurityPolicyUid));
aTzSession.LocalizationOpenDbL();
OpenDbL();
}
TBool CTzLocalizationDbAccessor::DbNeedsUpdatingL()
{
// Check the version of the database
// There are 9 columns as of Oct 2006
PrepareZoneViewL();
if (iZoneView.ColCount() == ETzZoneCityIndex)
{
return EFalse;
}
return ETrue;
}
/**
Releases the mutex if leave occurs between wait and signal.
@internalTechnology
*/
void CTzLocalizationDbAccessor::ReleaseMutex(TAny *target)
{
RMutex *mutex = static_cast<RMutex*> (target) ;
mutex->Signal() ;
}
/**
Creates the Cached Zone Table if it doesn't already exist.
@return KErrNone if succesful, or one of the DBMS Leave codes
@internalTechnology
*/
TInt CTzLocalizationDbAccessor::CreateFrequentlyUsedZoneTableL()
{
// Create the columns for the cached zones table
RArray<TDbCol> cachedTableCols;
CleanupClosePushL(cachedTableCols);
cachedTableCols.AppendL(TDbCol(KCZTableTzIdCol, EDbColUint16));
cachedTableCols.AppendL(TDbCol(KCZTableStdCol, EDbColText));
cachedTableCols.AppendL(TDbCol(KCZTableDSTCol, EDbColText));
cachedTableCols.AppendL(TDbCol(KCZTableShortStdCol, EDbColText));
cachedTableCols.AppendL(TDbCol(KCZTableShortDSTCol, EDbColText));
cachedTableCols.AppendL(TDbCol(KCZTableCityCol, EDbColText));
cachedTableCols.AppendL(TDbCol(KCZTableCityGroupCol, EDbColUint8));
cachedTableCols.AppendL(TDbCol(KCZTableResourceIdCol, EDbColUint32));
cachedTableCols.AppendL(TDbCol(KCZTableCityIndexCol, EDbColInt32));
// Create the columnset - add the columns
// Columns MUST be added in the same order they appear in TTzZoneColumn
CDbColSet* FrequentlyUsedZoneColSet = CDbColSet::NewLC();
TInt numCols = cachedTableCols.Count();
for(TInt i = 0; i < numCols; ++i)
{
FrequentlyUsedZoneColSet->AddL(cachedTableCols[i]);
}
// Create the Cached Time Zone table
TInt error = iLocalizedTimeZoneDb.CreateTable(KCZTableName,*FrequentlyUsedZoneColSet);
User::LeaveIfError(error);
//Open the newly created table
PrepareZoneViewL();
iZoneView.Reset();
//Populate with initial (blank) data.
_LIT(KEmptyString," ");
for (TInt x = 0; x < CTzLocalizedTimeZone::ECachedTimeZones; ++x)
{
iZoneMutex.Wait() ;
CleanupStack::PushL(TCleanupItem(ReleaseMutex,&iZoneMutex));
// Insert empty row
iZoneView.InsertL();
// Fill the table with blank data
iZoneView.SetColL(ETzZoneId, 0);
iZoneView.SetColL(ETzZoneStdName, KEmptyString);
iZoneView.SetColL(ETzZoneDSTName, KEmptyString);
iZoneView.SetColL(ETzZoneShortStdName, KEmptyString);
iZoneView.SetColL(ETzZoneShortDSTName, KEmptyString);
iZoneView.SetColL(ETzZoneCity, KEmptyString);
iZoneView.SetColL(ETzZoneGroupId, 0);
iZoneView.SetColL(ETzZoneResourceId, 0);
iZoneView.SetColL(ETzZoneCityIndex, 0);
iZoneView.PutL(); // Complete insertion
CleanupStack::Pop() ;
iZoneMutex.Signal() ;
}
iZoneView.Close();
CleanupStack::PopAndDestroy(FrequentlyUsedZoneColSet);
CleanupStack::PopAndDestroy(&cachedTableCols); //cachedTableCols
return error;
}
/**
Creates the user added city database table if it doesn't exist
@return KErrNone if succesful, or one of the DBMS Leave codes
@internalTechnology
*/
TInt CTzLocalizationDbAccessor::CreateUserCityTableL()
{
//Create the columns for the user aded cities table
RArray<TDbCol> cityTableCols;
CleanupClosePushL(cityTableCols);
cityTableCols.AppendL(TDbCol(KUCTableTzId, EDbColUint16));
cityTableCols.AppendL(TDbCol(KUCTableCity, EDbColText));
cityTableCols.AppendL(TDbCol(KUCTableGroup, EDbColUint8));
cityTableCols.AppendL(TDbCol(KUCTableResourceId, EDbColUint32));
// Create the columnset - add the columns
// Columns MUST be added in the same order they appear in TTzCityColumn
CDbColSet* userCityColSet = CDbColSet::NewLC();
TInt numCols = cityTableCols.Count();
for(TInt i = 0; i < numCols; ++i)
{
userCityColSet->AddL(cityTableCols[i]);
}
// Create the User City table
TInt error = iLocalizedTimeZoneDb.CreateTable(KUCTableName,*userCityColSet);
CleanupStack::PopAndDestroy(userCityColSet);
CleanupStack::PopAndDestroy(); //cityTableCols
return error;
}
/**
Opens the a view on the city table and returns a reference to it.
The view should be released after use with a call to CloseCityView()
@param aSql A sql string to prepare the view with
@return reference to opened iCityTable
@internalTechnology
*/
void CTzLocalizationDbAccessor::PrepareCityViewL(const TDesC& aSqlQuery)
{
User::LeaveIfError(
iCityView.Prepare(iLocalizedTimeZoneDb,
TDbQuery(aSqlQuery),
iCityView.EUpdatable)
);
User::LeaveIfError(iCityView.EvaluateAll());
}
/**
Opens the zone table and returns a reference
@return reference to the opened iZoneTable
@internalTechnology
*/
void CTzLocalizationDbAccessor::PrepareZoneViewL()
{
_LIT(KReadZoneView,"SELECT * FROM FrequentlyUsedZones");
User::LeaveIfError(
iZoneView.Prepare(iLocalizedTimeZoneDb,
TDbQuery(KReadZoneView),
iZoneView.EUpdatable)
);
User::LeaveIfError(iZoneView.EvaluateAll());
}