persistentstorage/sql/OsLayer/os_symbian.cpp
changeset 15 3eacc0623088
parent 0 08ec8eefde2f
child 17 55f2396f6d25
equal deleted inserted replaced
14:15018f1726c7 15:3eacc0623088
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
   698 public:
   698 public:
   699 	RFs			iFs;		//File session instance.
   699 	RFs			iFs;		//File session instance.
   700 	TFileName	iSysPrivDir;//"<system drive>:\" + process's private data path. Initialized in sqlite3SymbianFsOpen().
   700 	TFileName	iSysPrivDir;//"<system drive>:\" + process's private data path. Initialized in sqlite3SymbianFsOpen().
   701 							//Used for storing sqlite temporary files.
   701 							//Used for storing sqlite temporary files.
   702 	TInt64		iSeed;
   702 	TInt64		iSeed;
   703 	RAllocator*	iAllocator;
   703 
   704 
       
   705 	enum {KZeroBufSize = SQLITE_DEFAULT_SECTOR_SIZE};
       
   706     TBuf8<KZeroBufSize> iZeroBuf;
       
   707 	
       
   708 private:	
   704 private:	
   709 	static COsLayerData* 	iOsLayerData;
   705 	static COsLayerData* 	iOsLayerData;
   710 	TInt					iStoredOsErrorCode;	//Contains the last OS error code.
   706 	TInt					iStoredOsErrorCode;	//Contains the last OS error code.
   711 	const RMessage2* 		iMessage;			//Fh data
   707 	const RMessage2* 		iMessage;			//Fh data
   712 	TBool					iReadOnly;			//Fh data
   708 	TBool					iReadOnly;			//Fh data
   713 	};
   709 	};
       
   710 
       
   711 /**
       
   712 This functon returns a reference to the current thread allocator object.
       
   713 The static RAllocator& variable will be initialized once at the moment when the function is called for 
       
   714 first time. 
       
   715 */
       
   716 static RAllocator& Allocator()
       
   717     {
       
   718     static RAllocator& allocator = User::Allocator();
       
   719     return allocator;
       
   720     }
   714 
   721 
   715 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   722 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   716 ///////////////////////////////////       TDbFile struct declaration      /////////////////////////////////////////////////////
   723 ///////////////////////////////////       TDbFile struct declaration      /////////////////////////////////////////////////////
   717 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   724 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   718 
   725 
   817 	static TInt DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly);
   824 	static TInt DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly);
   818 	static inline TInt DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo);
   825 	static inline TInt DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo);
   819 	static TInt DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   826 	static TInt DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   820 	static TInt DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   827 	static TInt DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   821 	static TInt DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize);
   828 	static TInt DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize);
   822 	
   829 	static TInt DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode);
   823 	};
   830 	};
   824 
   831 
   825 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   832 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   826 /////////////////////       Global variables, constants    ////////////////////////////////////////////////////////////////////
   833 /////////////////////       Global variables, constants    ////////////////////////////////////////////////////////////////////
   827 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   834 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1040 
  1047 
  1041 /**
  1048 /**
  1042 Initializes the COsLayerData data members with their default values.
  1049 Initializes the COsLayerData data members with their default values.
  1043 */
  1050 */
  1044 inline COsLayerData::COsLayerData() :
  1051 inline COsLayerData::COsLayerData() :
  1045 	iAllocator(0),
       
  1046 	iStoredOsErrorCode(KErrNone),
  1052 	iStoredOsErrorCode(KErrNone),
  1047 	iMessage(0),
  1053 	iMessage(0),
  1048 	iReadOnly(EFalse)
  1054 	iReadOnly(EFalse)
  1049 	{
  1055 	{
  1050 	TTime now;
  1056 	TTime now;
  1051 	now.UniversalTime();
  1057 	now.UniversalTime();
  1052 	iSeed = now.Int64();
  1058 	iSeed = now.Int64();
  1053    	iZeroBuf.FillZ(COsLayerData::KZeroBufSize);
       
  1054 	}
  1059 	}
  1055 
  1060 
  1056 /**
  1061 /**
  1057 Destroys the COsLayerData instance.
  1062 Destroys the COsLayerData instance.
  1058 
  1063 
  1082 @see TVfs
  1087 @see TVfs
  1083 @see TheVfsApi
  1088 @see TheVfsApi
  1084 */
  1089 */
  1085 TInt COsLayerData::DoCreate()
  1090 TInt COsLayerData::DoCreate()
  1086 	{
  1091 	{
  1087 	iAllocator = &User::Allocator();
       
  1088 	__FS_CALL(EFsOpFsConnect, 0);
  1092 	__FS_CALL(EFsOpFsConnect, 0);
  1089 	TInt err = iFs.Connect();
  1093 	TInt err = iFs.Connect();
  1090 	if(err != KErrNone)
  1094 	if(err != KErrNone)
  1091 		{
  1095 		{
  1092 		return err;	
  1096 		return err;	
  1445 
  1449 
  1446 /**
  1450 /**
  1447 SQLite OS porting layer API.
  1451 SQLite OS porting layer API.
  1448 
  1452 
  1449 Closes the file referred by aDbFile parameter.
  1453 Closes the file referred by aDbFile parameter.
  1450 If aDbFile, which is actually a pointer to a TDbFile instance, the iFullName data member is not NULL, 
  1454 If aDbFile.iFullName data member is not NULL, then the file will be deleted.
  1451 then the file will be deleted.
       
  1452 
  1455 
  1453 @param aDbFile A pointer to a TDbFile instance, than contains the file handle to be closed.
  1456 @param aDbFile A pointer to a TDbFile instance, than contains the file handle to be closed.
  1454 
  1457 
  1455 @return SQLITE_OK
  1458 @return SQLITE_OK
  1456 
  1459 
  1463 	__OS_CALL(EOsFileClose, 0, 0);
  1466 	__OS_CALL(EOsFileClose, 0, 0);
  1464 	__OSTIME_COUNTER(TheOsCallTicks[EOsFileClose], ::OsCallProfile(dbFile.iIsJournal, EOsFileClose), 0, 0);
  1467 	__OSTIME_COUNTER(TheOsCallTicks[EOsFileClose], ::OsCallProfile(dbFile.iIsJournal, EOsFileClose), 0, 0);
  1465 	__FS_CALL(EFsOpFileClose, 0);
  1468 	__FS_CALL(EFsOpFileClose, 0);
  1466 	dbFile.iFileBuf.Close();
  1469 	dbFile.iFileBuf.Close();
  1467 	if(dbFile.iFullName)
  1470 	if(dbFile.iFullName)
  1468 		{
  1471 		{//"iFullName" will not be NULL only when TVfs::Open() is called with SQLITE_OPEN_DELETEONCLOSE flag.
       
  1472 		 //That means - SQlite expects the file to be deleted after the file close operation. 
  1469 		__FS_CALL(EFsOpFileDelete, 0);
  1473 		__FS_CALL(EFsOpFileDelete, 0);
  1470 		(void)COsLayerData::Instance().iFs.Delete(*dbFile.iFullName);
  1474 		(void)COsLayerData::Instance().iFs.Delete(*dbFile.iFullName);
  1471 		delete dbFile.iFullName;
  1475 		delete dbFile.iFullName;
  1472 		}
  1476 		}
  1473 	return SQLITE_OK;
  1477 	return SQLITE_OK;
  2101 	aDbFile.iDeviceCharacteristics = TVfs::DoGetDeviceCharacteristics(driveInfo, volumeInfo);
  2105 	aDbFile.iDeviceCharacteristics = TVfs::DoGetDeviceCharacteristics(driveInfo, volumeInfo);
  2102 	aDbFile.iSectorSize = TVfs::DoGetSectorSize(driveInfo, volumeInfo);
  2106 	aDbFile.iSectorSize = TVfs::DoGetSectorSize(driveInfo, volumeInfo);
  2103 	aRecReadBufSize = volumeInfo.iRecReadBufSize;
  2107 	aRecReadBufSize = volumeInfo.iRecReadBufSize;
  2104 	return KErrNone;
  2108 	return KErrNone;
  2105 	}
  2109 	}
       
  2110 
       
  2111 /**
       
  2112 SQLite OS porting layer API.
       
  2113 
       
  2114 The behaviour of the RFile/RFile64::SetSize operation is not atomic for non-rugged drives. 
       
  2115 When RFile/RFile64::SetSize() is called 2 operations occurs:-
       
  2116 
       
  2117 1)The cluster chain of the file is updated.
       
  2118 2)The new file size is added to the file cache.
       
  2119 
       
  2120 If a power loss occurs after a SetSize there is a chance that the cluster chain was updated 
       
  2121 but the new file size is not yet flushed to the file. This puts the file into an inconsistent state.
       
  2122 This is most likely to occur in the journal file where the time between a SetSize and Flush can 
       
  2123 be long. 
       
  2124 
       
  2125 For this reason this check is added when the file is opened to see if the end of the file can 
       
  2126 be read straight away, if an error is returned then it is assumed that the SetSize has not be 
       
  2127 completed previously. In this case the file is deleted and re-created.
       
  2128  
       
  2129 @param aDbFile A pointer to a TDbFile instance, that contains the file handle.
       
  2130 @param aFname A string of 16-bit wide characters containing name of the file to be checked.
       
  2131 @param aFmode The mode in which the file is opened. These mode are documented in TFileMode.
       
  2132 
       
  2133 @return KErrNone,          The operation has completed succesfully;
       
  2134                            Note that other system-wide error codes may also be returned.
       
  2135 @see TFileMode
       
  2136 @see TVfs::Open()
       
  2137 @see TDbFile
       
  2138 */
       
  2139 /* static */ TInt TVfs::DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode)
       
  2140     {
       
  2141     const TInt KMinSize = 16;
       
  2142     TInt64 size;
       
  2143     TInt err = KErrNone ;
       
  2144     TBuf8<KMinSize> buf;
       
  2145 
       
  2146     err = aDbFile.iFileBuf.Size(size);
       
  2147     if (err != KErrNone)
       
  2148         {
       
  2149         return err;
       
  2150         }
       
  2151     TBool IsMinFileSize = (size >= KMinSize);
       
  2152     
       
  2153     if (IsMinFileSize)
       
  2154         {
       
  2155         err = aDbFile.iFileBuf.Read(size - KMinSize, buf);
       
  2156         }
       
  2157     
       
  2158     if (err == KErrCorrupt || err == KErrEof || !IsMinFileSize)
       
  2159         {
       
  2160         COsLayerData& osLayerData = COsLayerData::Instance();
       
  2161     
       
  2162         aDbFile.iFileBuf.Close();
       
  2163         (void) osLayerData.iFs.Delete(aFname);
       
  2164         err = aDbFile.iFileBuf.Create(osLayerData.iFs, aFname, aFmode);
       
  2165         }
       
  2166     return err;
       
  2167     }
  2106 
  2168 
  2107 /**
  2169 /**
  2108 SQLite OS porting layer API.
  2170 SQLite OS porting layer API.
  2109 
  2171 
  2110 Opens or creates a file which name is in the aFileName parameter.
  2172 Opens or creates a file which name is in the aFileName parameter.
  2209 				}
  2271 				}
  2210 			if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull)
  2272 			if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull)
  2211 				{
  2273 				{
  2212 				__FS_CALL(EFsOpFileOpen, 0);
  2274 				__FS_CALL(EFsOpFileOpen, 0);
  2213 				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2275 				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
       
  2276 				
       
  2277 				if(err == KErrNone && ((aFlags & SQLITE_OPEN_MAIN_JOURNAL) || (aFlags & SQLITE_OPEN_TEMP_JOURNAL) || 
       
  2278                         (aFlags & SQLITE_OPEN_SUBJOURNAL) || (aFlags & SQLITE_OPEN_MASTER_JOURNAL)))
       
  2279 				    {
       
  2280                     err = TVfs::DoFileSizeCorruptionCheck(dbFile, fname, fmode);
       
  2281 				    }
  2214 				}
  2282 				}
  2215 			if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE))
  2283 			if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE))
  2216 				{
  2284 				{
  2217 				aFlags &= ~SQLITE_OPEN_READWRITE;
  2285 				aFlags &= ~SQLITE_OPEN_READWRITE;
  2218 				aFlags |= SQLITE_OPEN_READONLY;
  2286 				aFlags |= SQLITE_OPEN_READONLY;
  2219 				fmode &= ~EFileWrite;
  2287 				fmode &= ~EFileWrite;
  2220 				__FS_CALL(EFsOpFileOpen, 0);
  2288 				__FS_CALL(EFsOpFileOpen, 0);
  2221    				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2289    				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2222    				}
  2290 				}
  2223 			if(err != KErrNone && prevErr == KErrAccessDenied)
  2291 			if(err != KErrNone && prevErr == KErrAccessDenied)
  2224 				{
  2292 				{
  2225 				err = KErrAccessDenied;
  2293 				err = KErrAccessDenied;
  2226 				}
  2294 				}
  2227 			}
  2295 			}
  2235 		{
  2303 		{
  2236 		__FS_CALL(EFsOpFileClose, 0);
  2304 		__FS_CALL(EFsOpFileClose, 0);
  2237 		dbFile.iFileBuf.Close();	
  2305 		dbFile.iFileBuf.Close();	
  2238 		delete dbFile.iFullName;
  2306 		delete dbFile.iFullName;
  2239 		dbFile.iFullName = NULL;
  2307 		dbFile.iFullName = NULL;
       
  2308         if(!aFileName && fname.Length() > 0)
       
  2309             {//temporary file, the error is not KErrNone. Then delete the file (after a successfull 
       
  2310              //temporary file creation there could be a failed memory allocation)
       
  2311             (void)osLayerData.iFs.Delete(fname);
       
  2312             }
  2240 		}
  2313 		}
  2241 	else
  2314 	else
  2242 		{
  2315 		{
  2243 		dbFile.pMethods = &TheFileIoApi;
  2316 		dbFile.pMethods = &TheFileIoApi;
  2244 		if(fhStrType != EFhMainDbStr)
  2317 		if(fhStrType != EFhMainDbStr)
  2548 @internalComponent
  2621 @internalComponent
  2549 */
  2622 */
  2550 extern "C" void* sqlite3SymbianMalloc(size_t aSize)
  2623 extern "C" void* sqlite3SymbianMalloc(size_t aSize)
  2551 	{
  2624 	{
  2552 	__MEM_CALL(EMemOpAlloc, aSize, 0);
  2625 	__MEM_CALL(EMemOpAlloc, aSize, 0);
  2553 	return COsLayerData::Instance().iAllocator->Alloc(aSize);
  2626 	return Allocator().Alloc(aSize);
  2554 	}
  2627 	}
  2555 
  2628 
  2556 /**
  2629 /**
  2557 SQLite OS porting layer API.
  2630 SQLite OS porting layer API.
  2558 
  2631 
  2561 @internalComponent
  2634 @internalComponent
  2562 */
  2635 */
  2563 extern "C" void* sqlite3SymbianRealloc(void* aPtr, size_t aSize)
  2636 extern "C" void* sqlite3SymbianRealloc(void* aPtr, size_t aSize)
  2564 	{
  2637 	{
  2565 #ifdef _SQLPROFILER
  2638 #ifdef _SQLPROFILER
  2566 	TInt size = COsLayerData::Instance().iAllocator->AllocLen(aPtr);
  2639 	TInt size = Allocator().AllocLen(aPtr);
  2567 	__MEM_CALL(EMemOpRealloc, aSize, size);
  2640 	__MEM_CALL(EMemOpRealloc, aSize, size);
  2568 #endif
  2641 #endif
  2569 	return COsLayerData::Instance().iAllocator->ReAlloc(aPtr, aSize);
  2642 	return Allocator().ReAlloc(aPtr, aSize);
  2570 	}
  2643 	}
  2571 
  2644 
  2572 /**
  2645 /**
  2573 SQLite OS porting layer API.
  2646 SQLite OS porting layer API.
  2574 
  2647 
  2577 @internalComponent
  2650 @internalComponent
  2578 */
  2651 */
  2579 extern "C" void sqlite3SymbianFree(void* aPtr)
  2652 extern "C" void sqlite3SymbianFree(void* aPtr)
  2580 	{
  2653 	{
  2581 #ifdef _SQLPROFILER
  2654 #ifdef _SQLPROFILER
  2582 	TInt size = COsLayerData::Instance().iAllocator->AllocLen(aPtr);
  2655 	TInt size = Allocator().AllocLen(aPtr);
  2583 	__MEM_CALL(EMemOpFree, size, 0);
  2656 	__MEM_CALL(EMemOpFree, size, 0);
  2584 #endif
  2657 #endif
  2585 	COsLayerData::Instance().iAllocator->Free(aPtr);
  2658 	Allocator().Free(aPtr);
  2586 	}
  2659 	}
  2587 
  2660 
  2588 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2661 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2589 ///////////////////////////////////       SQLite init/release functions     ///////////////////////////////////////////////////
  2662 ///////////////////////////////////       SQLite init/release functions     ///////////////////////////////////////////////////
  2590 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2663 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////