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 |
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) |
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 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |