sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // DBMS client/server session class
sl@0: // 
sl@0: //
sl@0: 
sl@0: #include "SD_STD.H"
sl@0: 
sl@0: const TInt KTimesToRetryConnection = 2;
sl@0: 
sl@0: 
sl@0: // Class RDbs
sl@0: 
sl@0: /** Returns the version of the DBMS server.
sl@0: 
sl@0: @return Version information. */
sl@0: EXPORT_C TVersion RDbs::Version()
sl@0: 	{
sl@0: 	return TVersion(KDbmsMajorVersion,KDbmsMinorVersion,KDbmsBuildVersion);
sl@0: 	}
sl@0: 
sl@0: /** Makes a connection with the DBMS server. This function causes the server to 
sl@0: start, if it is not already running.
sl@0: 
sl@0: This should be the first function called on an RDbs object after it is created.
sl@0: 
sl@0: Once a connection has been established, databases can be opened through the 
sl@0: server.
sl@0: 
sl@0: Note that:
sl@0: 
sl@0: Threads can make any number of simultaneous connections to the DBMS server.
sl@0: 
sl@0: The session must stay open until all DBMS objects opened through the server 
sl@0: have been closed.
sl@0: 
sl@0: The session is terminated by calling the Close() member function provided 
sl@0: by the RSessionBase class.
sl@0: 
sl@0: @return KErrNone if successful, otherwise another of the system-wide error 
sl@0: codes. */
sl@0: EXPORT_C TInt RDbs::Connect()
sl@0: 	{
sl@0: 	TInt retry = KTimesToRetryConnection;
sl@0: 	for (;;)
sl@0: 		{
sl@0: 		TInt r=DoConnect();
sl@0: 		if (r!=KErrNotFound && r!=KErrServerTerminated)
sl@0: 			return r;
sl@0: 		if (--retry==0)
sl@0: 			return r;
sl@0: 		r=Dbs::Start();
sl@0: 		if (r!=KErrNone && r!=KErrAlreadyExists)
sl@0: 			return r;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: /** Marks the start point for checking the number of DBMS objects allocated in 
sl@0: this session.
sl@0: 
sl@0: The function takes the current number of allocated DBMS objects as its benchmark 
sl@0: number.
sl@0: 
sl@0: A call to this function is normally followed by a later call to ResourceCheck() 
sl@0: which expects that the number of allocated DBMS objects to be the same as 
sl@0: this benchmark number. */
sl@0: EXPORT_C void RDbs::ResourceMark()
sl@0: 	{
sl@0: 	SessionMessage(EDbsResourceMark);
sl@0: 	}
sl@0: 
sl@0: /** Checks that the number of DBMS objects allocated in this session is the same 
sl@0: as the benchmark number recorded by an earlier call to ResourceMark().
sl@0: 
sl@0: The function raises a CSession 2 panic if the current number of DBMS objects 
sl@0: is not the same as that recorded by an earlier call to ResourceMark(). */
sl@0: EXPORT_C void RDbs::ResourceCheck()
sl@0: 	{
sl@0: 	SessionMessage(EDbsResourceCheck);
sl@0: 	}
sl@0: 
sl@0: /** Returns the number of DBMS objects allocated in this session.
sl@0: 
sl@0: @return The number of DBMS allocated objects. */
sl@0: EXPORT_C TInt RDbs::ResourceCount()
sl@0: 	{
sl@0: 	return SessionMessage(EDbsResourceCount);
sl@0: 	}
sl@0: 
sl@0: EXPORT_C void RDbs::SetHeapFailure(TInt aTAllocFail,TInt aRate)
sl@0: 	{
sl@0: 	SendReceive(DbsMessage(EDbsSetHeapFailure,KDbsSessionHandle),TIpcArgs(aTAllocFail,aRate));
sl@0: 	}
sl@0: 
sl@0: TInt RDbs::SessionMessage(TInt aFunction)
sl@0: 	{
sl@0: 	return SendReceive(DbsMessage(aFunction,KDbsSessionHandle));
sl@0: 	}
sl@0: 
sl@0: // Create the session
sl@0: TInt RDbs::DoConnect()
sl@0: 	{
sl@0: 	return CreateSession(KDbsServerName,Version());
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Reserves a prederfined amount of disk space on aDrive drive. 
sl@0: At the moment the max possible amount, allowed by the file server, is reserved on aDrive drive.
sl@0: 
sl@0: Use this call to ensure that if your "delete records" transaction fails because of "out of
sl@0: disk space" circumstances, you can get an access to the already reserved disk space and 
sl@0: complete your transaction successfully the second time.
sl@0: 
sl@0: There is no strong, 100% guarantee, that the reserved disk space will always help the client
sl@0: in "low memory" situations.
sl@0: 
sl@0: @param aDriveNo Drive number to reserve space on
sl@0: @param aSpace This parameter is not used at the moment. The caller shall set it to 0.
sl@0: @return KErrNoMemory Out of memory
sl@0:         KErrArgument Invalid aDriveNo.
sl@0:         KErrInUse The space has already been reserved
sl@0:         RFs::ReserveDriveSpace() return value
sl@0: @see RFs::ReserveDriveSpace()
sl@0: */
sl@0: EXPORT_C TInt RDbs::ReserveDriveSpace(TInt aDriveNo, TInt /*aSpace*/)
sl@0: 	{
sl@0: 	return SendReceive(DbsMessage(EDbsReserveDriveSpace, KDbsSessionHandle), TIpcArgs(aDriveNo));
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: The method frees the reserved by the DBMS session disk space.
sl@0: 
sl@0: @param aDriveNo Drive number, which reserved space has to be freed.
sl@0: @panic In debug mode there will be a panic with the line number as an error code if 
sl@0:        there is no reserved disk space for aDrive. 
sl@0: @panic In debug mode there will be a panic with the line number as an error code if 
sl@0:        the reserved disk space is granted but not released.
sl@0: */
sl@0: EXPORT_C void RDbs::FreeReservedSpace(TInt aDriveNo)
sl@0:     {
sl@0: 	(void)SendReceive(DbsMessage(EDbsFreeReservedSpace, KDbsSessionHandle), TIpcArgs(aDriveNo));
sl@0:     }
sl@0: 
sl@0: /**
sl@0: Grants access to a given area on a given drive for RDbs session.
sl@0: Note this session must have reserved space on this particular drive in order to be 
sl@0: granted access to the reserved area.
sl@0: 
sl@0: @param aDriveNo Drive number with a reserved disk space, an access to which is requested.
sl@0: @return KErrArgument Invalid drive or there is no reserved disk space on aDriveNo.
sl@0:         KErrInUse An access to the reserved space has already been given.
sl@0:         RFs::GetReserveAccess() return values
sl@0: @see RFs::GetReserveAccess()
sl@0: */
sl@0: EXPORT_C TInt RDbs::GetReserveAccess(TInt aDriveNo)
sl@0: 	{
sl@0: 	return SendReceive(DbsMessage(EDbsReserveGetAccess, KDbsSessionHandle), TIpcArgs(aDriveNo));
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: Revokes access on a given drive for RDbs session.
sl@0: 
sl@0: @param aDriveNo Drive number with a reserved disk space, the access to which has to be released.
sl@0: @return KErrNone.
sl@0: @panic In debug mode there will be a panic with the line number as an error code if 
sl@0:        there is no reserved disk space for aDrive. 
sl@0: @panic In debug mode there will be a panic with the line number as an error code if 
sl@0:        there is no granted access to the reserved disk space. 
sl@0: */
sl@0: EXPORT_C TInt RDbs::ReleaseReserveAccess(TInt aDriveNo)
sl@0: 	{
sl@0: 	(void)SendReceive(DbsMessage(EDbsReserveReleaseAccess, KDbsSessionHandle), TIpcArgs(aDriveNo));
sl@0:     return KErrNone;
sl@0: 	}
sl@0: 
sl@0: // Class RDbNamedDatabase
sl@0: 
sl@0: 
sl@0: /**
sl@0: Opens an existing shared secure or non-secure database.
sl@0: Max allowed database name length (with the extension) is KDbMaxName symbols.
sl@0: 
sl@0: In this "client-server" mode the database can be shared with the other clients.
sl@0: 
sl@0: For opening a single, non-shareable connection to the database, see RDbNamedDatabase::Open(), which first
sl@0: argument is a RFs reference.
sl@0: 
sl@0: @param aDbs A reference to DBMS session instance.
sl@0: @param aDatabase The name of the file that hosts the database. If this is
sl@0:                  a secure database, then the format of the name must be:
sl@0:                  \<drive\>:\<database file name excluding the path\>.
sl@0:                  If this is a non-secure database, then aDatabase has to be the full database file name.
sl@0: @param aFormat Database format string. For shared secure databases the string format is: "SECURE[UID]", 
sl@0: 			   where UID is the database security policy UID. "SECURE" keyword is case insensitive.
sl@0: 			   For shared non-secure databases, the default parameter value (TPtrC()) can be used.
sl@0: @return KErrNone if successful otherwise one of the system-wide error codes, including:
sl@0: 		KErrNotFound - the database is not found;
sl@0: 		KErrArgument - bad argument, including null/invaluid uids, the database name includes a path;
sl@0: 		KErrPermissionDenied - the caller has not enough rights to do the operation;
sl@0: 
sl@0: @capability Note For a secure shared database, the caller must satisfy the read,
sl@0:             the write or the schema access policy for the database.
sl@0: 
sl@0: @see RDbNamedDatabase::Open(RFs& aFs, const TDesC& aSource, const TDesC& aFormat, TAccess aMode).
sl@0: 
sl@0: @publishedAll
sl@0: @released
sl@0: */
sl@0: EXPORT_C TInt RDbNamedDatabase::Open(RDbs& aDbs, const TDesC& aDatabase, const TDesC& aFormat)
sl@0: 	{
sl@0: 	TRAPD(r,iDatabase=CDbsDatabase::NewL(aDbs,aDatabase,aFormat));
sl@0: 	return r;
sl@0: 	}
sl@0: