persistentstorage/sql/OsLayer/os_symbian.cpp
branchRCL_3
changeset 21 28839de615b4
parent 15 fcc16690f446
child 23 26645d81f48d
equal deleted inserted replaced
18:3da531bb4329 21:28839de615b4
    81 	EPanicInvalidSectorSize		=18,
    81 	EPanicInvalidSectorSize		=18,
    82 	EPanicInternalError			=19,
    82 	EPanicInternalError			=19,
    83 	EPanicNullDbFilePtr			=20,
    83 	EPanicNullDbFilePtr			=20,
    84 	EPanicFastCounterFreq		=21
    84 	EPanicFastCounterFreq		=21
    85 	};
    85 	};
       
    86 
       
    87 //The SQLite temp files willl be created in this subdir
       
    88 _LIT(KTempFileDir, "temp");
    86 
    89 
    87 //Bit-mask constant. If xOpen()'s "aFlag" parameter contains one of these bits set, then the the file top be
    90 //Bit-mask constant. If xOpen()'s "aFlag" parameter contains one of these bits set, then the the file top be
    88 //opened or created is a journal file.
    91 //opened or created is a journal file.
    89 const TUint KJournalFileTypeBitMask = SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL; 
    92 const TUint KJournalFileTypeBitMask = SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL; 
    90 
    93 
   419 						{
   422 						{
   420 						TPtrC8 fn8(iOptional);
   423 						TPtrC8 fn8(iOptional);
   421 						fname.Copy(fn8);
   424 						fname.Copy(fn8);
   422 						}
   425 						}
   423 					//                                           0    1  2  3  4  5   6  7   8   9   10
   426 					//                                           0    1  2  3  4  5   6  7   8   9   10
   424 					RDebug::Print(_L("[SQL-OS]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬%c¬%S¬%d¬%d¬%ld¬%d¬%ld¬%ld¬%ld¬%S\n"),
   427 					RDebug::Print(_L("[SQL-OS]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬%c¬%S¬%d¬%d¬%ld¬%d¬%ld¬%ld¬%ld¬%S\r\n"),
   425 															//[SQL-OS]
   428 															//[SQL-OS]
   426 															//Handle
   429 															//Handle
   427 															//Time from start, microseconds
   430 															//Time from start, microseconds
   428 															//Subtype
   431 															//Subtype
   429 															//IPC sequence counter
   432 															//IPC sequence counter
   718 	TInt DoCreate();
   721 	TInt DoCreate();
   719 	
   722 	
   720 public:
   723 public:
   721 	RFs			iFs;		//File session instance.
   724 	RFs			iFs;		//File session instance.
   722 	TFileName	iSysPrivDir;//"<system drive>:\" + process's private data path. Initialized in sqlite3SymbianFsOpen().
   725 	TFileName	iSysPrivDir;//"<system drive>:\" + process's private data path. Initialized in sqlite3SymbianFsOpen().
   723 							//Used for storing sqlite temporary files.
       
   724 	TInt64		iSeed;
   726 	TInt64		iSeed;
   725 
   727 
   726 private:	
   728 private:	
   727 	static COsLayerData* 	iOsLayerData;
   729 	static COsLayerData* 	iOsLayerData;
   728 	TInt					iStoredOsErrorCode;	//Contains the last OS error code.
   730 	TInt					iStoredOsErrorCode;	//Contains the last OS error code.
   765 */
   767 */
   766 NONSHARABLE_STRUCT(TDbFile) : public sqlite3_file 
   768 NONSHARABLE_STRUCT(TDbFile) : public sqlite3_file 
   767 	{
   769 	{
   768 	inline TDbFile();
   770 	inline TDbFile();
   769 	RFileBuf64	iFileBuf;
   771 	RFileBuf64	iFileBuf;
   770 	HBufC*		iFullName;				//Used for the "delete file" operation (RFile64::FullName() makes an IPC call!)
       
   771 	TInt		iLockType;				//File lock type
   772 	TInt		iLockType;				//File lock type
   772 	TBool		iReadOnly;				//True if the file is read-only
   773 	TBool		iReadOnly;				//True if the file is read-only
   773 	TInt		iSectorSize;			//Media sector-size
   774 	TInt		iSectorSize;			//Media sector-size
   774 	TInt		iDeviceCharacteristics;
   775 	TInt		iDeviceCharacteristics;
   775 	TSqlFreePageCallback iFreePageCallback;
   776 	TSqlFreePageCallback iFreePageCallback;
       
   777 	TBool       iIsFileCreated;          //If the file to be created is a temp file, 
       
   778                                        //it will not be created until the data is to be written to.
   776 #ifdef _SQLPROFILER
   779 #ifdef _SQLPROFILER
   777 	TBool		iIsJournal;
   780 	TBool		iIsJournal;
   778 #endif	
   781 #endif	
   779 	};
   782 	};
   780 
   783 
   812 	static int Unlock(sqlite3_file* aDbFile, int aLockType);
   815 	static int Unlock(sqlite3_file* aDbFile, int aLockType);
   813 	static int CheckReservedLock(sqlite3_file* aDbFile, int *aResOut);
   816 	static int CheckReservedLock(sqlite3_file* aDbFile, int *aResOut);
   814 	static int FileControl(sqlite3_file* aDbFile, int aOp, void* aArg);
   817 	static int FileControl(sqlite3_file* aDbFile, int aOp, void* aArg);
   815 	static int SectorSize(sqlite3_file* aDbFile);
   818 	static int SectorSize(sqlite3_file* aDbFile);
   816 	static int DeviceCharacteristics(sqlite3_file* aDbFile);
   819 	static int DeviceCharacteristics(sqlite3_file* aDbFile);
       
   820 private:
       
   821 	static TInt DoCreateTempFile(TDbFile& aDbFile);
   817 	};
   822 	};
   818 
   823 
   819 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   824 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   820 ///////////////////////////////////       TVfs class declaration      /////////////////////////////////////////////////////////
   825 ///////////////////////////////////       TVfs class declaration      /////////////////////////////////////////////////////////
   821 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   826 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   840 	static int FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf);
   845 	static int FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf);
   841 	static int Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf);
   846 	static int Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf);
   842 	static int Sleep(sqlite3_vfs* aVfs, int aMicrosec);
   847 	static int Sleep(sqlite3_vfs* aVfs, int aMicrosec);
   843 	static int CurrentTime(sqlite3_vfs* aVfs, double* aNow);
   848 	static int CurrentTime(sqlite3_vfs* aVfs, double* aNow);
   844 	static int GetLastError(sqlite3_vfs *sVfs, int aBufLen, char* aBuf);
   849 	static int GetLastError(sqlite3_vfs *sVfs, int aBufLen, char* aBuf);
       
   850     static TInt DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize);
       
   851 
   845 private:
   852 private:
   846 	static TInt DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly);
   853 	static TInt DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly);
   847 	static inline TInt DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo);
   854 	static inline TInt DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo);
   848 	static TInt DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   855 	static TInt DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   849 	static TInt DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   856 	static TInt DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   850 	static TInt DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize);
       
   851 	static TInt DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode);
   857 	static TInt DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode);
   852 	};
   858 	};
   853 
   859 
   854 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   860 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   855 /////////////////////       Global variables, constants    ////////////////////////////////////////////////////////////////////
   861 /////////////////////       Global variables, constants    ////////////////////////////////////////////////////////////////////
  1134 	TDriveUnit drive(sysDrive);
  1140 	TDriveUnit drive(sysDrive);
  1135 	TDriveName driveName = drive.Name();
  1141 	TDriveName driveName = drive.Name();
  1136 	TParse parse;
  1142 	TParse parse;
  1137 	(void)parse.Set(driveName, &privateDir, 0);//this call can't fail
  1143 	(void)parse.Set(driveName, &privateDir, 0);//this call can't fail
  1138 	iSysPrivDir.Copy(parse.DriveAndPath());
  1144 	iSysPrivDir.Copy(parse.DriveAndPath());
       
  1145 	//Create the temp files directory
       
  1146 	(void)parse.AddDir(KTempFileDir);//this call can't fail
       
  1147 	err = iFs.MkDir(parse.DriveAndPath());
       
  1148     if(err != KErrNone && err != KErrAlreadyExists)
       
  1149     	{
       
  1150 		return err;
       
  1151     	}
  1139 	return KErrNone;
  1152 	return KErrNone;
  1140 	}
  1153 	}
  1141 
  1154 
  1142 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1155 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1143 ///////////////////////     Symbian OS specific functions (called by the SQL server)        ///////////////////////////////////
  1156 ///////////////////////     Symbian OS specific functions (called by the SQL server)        ///////////////////////////////////
  1444 /**
  1457 /**
  1445 Initializes TDbFile data members with their default values.
  1458 Initializes TDbFile data members with their default values.
  1446 */
  1459 */
  1447 inline TDbFile::TDbFile() :
  1460 inline TDbFile::TDbFile() :
  1448 	iFileBuf(KFileBufSize),
  1461 	iFileBuf(KFileBufSize),
  1449 	iFullName(0),
       
  1450 	iLockType(SQLITE_LOCK_NONE),
  1462 	iLockType(SQLITE_LOCK_NONE),
  1451 	iReadOnly(EFalse),
  1463 	iReadOnly(EFalse),
  1452 	iSectorSize(0),
  1464 	iSectorSize(0),
  1453 	iDeviceCharacteristics(-1)
  1465 	iDeviceCharacteristics(-1),
       
  1466 	iIsFileCreated(ETrue)
  1454 	{
  1467 	{
  1455 #ifdef _SQLPROFILER
  1468 #ifdef _SQLPROFILER
  1456 	iIsJournal = EFalse;
  1469 	iIsJournal = EFalse;
  1457 #endif
  1470 #endif
  1458 	pMethods = 0;
  1471 	pMethods = 0;
  1486 
  1499 
  1487 /**
  1500 /**
  1488 SQLite OS porting layer API.
  1501 SQLite OS porting layer API.
  1489 
  1502 
  1490 Closes the file referred by aDbFile parameter.
  1503 Closes the file referred by aDbFile parameter.
  1491 If aDbFile.iFullName data member is not NULL, then the file will be deleted.
       
  1492 
  1504 
  1493 @param aDbFile A pointer to a TDbFile instance, than contains the file handle to be closed.
  1505 @param aDbFile A pointer to a TDbFile instance, than contains the file handle to be closed.
  1494 
  1506 
  1495 @return SQLITE_OK
  1507 @return SQLITE_OK
  1496 
  1508 
  1501 	SQLUTRACE_PROFILER(aDbFile);
  1513 	SQLUTRACE_PROFILER(aDbFile);
  1502 	TDbFile& dbFile = ::DbFile(aDbFile);
  1514 	TDbFile& dbFile = ::DbFile(aDbFile);
  1503 	__OS_CALL(EOsFileClose, 0, 0);
  1515 	__OS_CALL(EOsFileClose, 0, 0);
  1504 	__OSTIME_COUNTER(TheOsCallTicks[EOsFileClose], ::OsCallProfile(dbFile.iIsJournal, EOsFileClose), 0, 0, aDbFile, 0);
  1516 	__OSTIME_COUNTER(TheOsCallTicks[EOsFileClose], ::OsCallProfile(dbFile.iIsJournal, EOsFileClose), 0, 0, aDbFile, 0);
  1505 	__FS_CALL(EFsOpFileClose, 0);
  1517 	__FS_CALL(EFsOpFileClose, 0);
  1506 	dbFile.iFileBuf.Close();
  1518   dbFile.iFileBuf.Close();
  1507 	if(dbFile.iFullName)
       
  1508 		{//"iFullName" will not be NULL only when TVfs::Open() is called with SQLITE_OPEN_DELETEONCLOSE flag.
       
  1509 		 //That means - SQlite expects the file to be deleted after the file close operation. 
       
  1510 		__FS_CALL(EFsOpFileDelete, 0);
       
  1511 		(void)COsLayerData::Instance().iFs.Delete(*dbFile.iFullName);
       
  1512 		delete dbFile.iFullName;
       
  1513 		}
       
  1514 	return SQLITE_OK;
  1519 	return SQLITE_OK;
  1515 	}
  1520 	}
  1516 
  1521 
  1517 /**
  1522 /**
  1518 SQLite OS porting layer API.
  1523 SQLite OS porting layer API.
  1571 		}
  1576 		}
  1572 	COsLayerData::Instance().SetOsErrorCode(err);
  1577 	COsLayerData::Instance().SetOsErrorCode(err);
  1573 	return sqliteErr;
  1578 	return sqliteErr;
  1574 	}
  1579 	}
  1575 
  1580 
       
  1581 //Creates a temporary file in "\temp" subdirectory of osLayerData.iSysPrivDir directory.
       
  1582 //If the function fails, the temp file will be closed and deleted, 
       
  1583 //the related Symbian OS error will be returned to the caller.
       
  1584 /* static */TInt TFileIo::DoCreateTempFile(TDbFile& aDbFile)
       
  1585     {
       
  1586     COsLayerData& osLayerData = COsLayerData::Instance();
       
  1587     //TParse2 is used in order to avoid the need of another TFileName stack based variable
       
  1588 	class TParse2 : public TParse
       
  1589 		{
       
  1590 	public:
       
  1591 		inline TFileName& FileName()
       
  1592 			{
       
  1593 			return static_cast <TFileName&> (NameBuf());
       
  1594 			}
       
  1595 		};
       
  1596 	TParse2 parse;
       
  1597 	(void)parse.Set(osLayerData.iSysPrivDir, 0, 0);//this call can't fail
       
  1598 	(void)parse.AddDir(KTempFileDir);//this call can't fail
       
  1599     __FS_CALL(EFsOpFileCreateTemp, 0);
       
  1600     TInt err = aDbFile.iFileBuf.Temp(osLayerData.iFs, parse.FullName(), parse.FileName(), EFileRead|EFileWrite|EDeleteOnClose);        
       
  1601     if(err == KErrPathNotFound)
       
  1602         {
       
  1603         err = osLayerData.iFs.MkDirAll(parse.DriveAndPath());
       
  1604         if(err == KErrNone)
       
  1605             {
       
  1606             err = aDbFile.iFileBuf.Temp(osLayerData.iFs, parse.FullName(), parse.FileName(), EFileRead|EFileWrite|EDeleteOnClose);
       
  1607             }
       
  1608         }
       
  1609     if(err == KErrNone)
       
  1610         {
       
  1611         TInt recReadBufSize = -1;
       
  1612         err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(aDbFile, recReadBufSize);
       
  1613         if(err != KErrNone)
       
  1614             {
       
  1615             aDbFile.iFileBuf.Close();//With EDeleteOnClose flag set, the file will be deleted
       
  1616             }
       
  1617         else
       
  1618             {
       
  1619             (void)aDbFile.iFileBuf.SetReadAheadSize(aDbFile.iSectorSize, recReadBufSize);
       
  1620             aDbFile.iIsFileCreated = ETrue;
       
  1621             }
       
  1622         }
       
  1623     return err;
       
  1624     }
       
  1625 
  1576 /**
  1626 /**
  1577 SQLite OS porting layer API.
  1627 SQLite OS porting layer API.
  1578 
  1628 
  1579 Writes to the file referred by the aDbFile parameter.
  1629 Writes to the file referred by the aDbFile parameter.
  1580 "Write beyond the end of the file" operations are allowed.
  1630 "Write beyond the end of the file" operations are allowed.
  1581 
  1631 
  1582 If the write operation is in the 1st db file page and there is a registered "free pages" callback 
  1632 If the write operation is in the 1st db file page and there is a registered "free pages" callback 
  1583 (TDbFile::iFreePageCallback) and the free pages count is above the defined value,
  1633 (TDbFile::iFreePageCallback) and the free pages count is above the defined value,
  1584 then the callback will be called.
  1634 then the callback will be called.
       
  1635 
       
  1636 If the file to be written to is a temp file, which is not created yet, then the file will be created.
  1585 
  1637 
  1586 @param aDbFile A pointer to a TDbFile instance, that contains the file handle to be written to.
  1638 @param aDbFile A pointer to a TDbFile instance, that contains the file handle to be written to.
  1587 @param aData The data to be written to the file. The buffer size must be at least aAmt bytes.
  1639 @param aData The data to be written to the file. The buffer size must be at least aAmt bytes.
  1588 @param aAmt The amount of data to be written to the file.
  1640 @param aAmt The amount of data to be written to the file.
  1589 @param aOffset The offset in the file where the write operation should start.
  1641 @param aOffset The offset in the file where the write operation should start.
  1602 /* static */ int TFileIo::Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset)
  1654 /* static */ int TFileIo::Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset)
  1603 	{
  1655 	{
  1604 	SQLUTRACE_PROFILER(aDbFile);
  1656 	SQLUTRACE_PROFILER(aDbFile);
  1605 	SYMBIAN_TRACE_SQL_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileWrite, aAmt, aOffset));
  1657 	SYMBIAN_TRACE_SQL_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileWrite, aAmt, aOffset));
  1606 	TDbFile& dbFile = ::DbFile(aDbFile);
  1658 	TDbFile& dbFile = ::DbFile(aDbFile);
  1607 	__OS_CALL(EOsFileWrite, 0, 0);
  1659 	TInt err = KErrNone;
       
  1660 	if(!dbFile.iIsFileCreated)
       
  1661 	    {//Create a temp file if it has not been created. 
       
  1662 	    err = TFileIo::DoCreateTempFile(dbFile);
       
  1663 	    }
       
  1664 	if(err != KErrNone)
       
  1665 	    {
       
  1666         COsLayerData::Instance().SetOsErrorCode(err);
       
  1667         return err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_FULL;
       
  1668 	    }
       
  1669 	
       
  1670     __OS_CALL(EOsFileWrite, 0, 0);
  1608     __COUNTER_INCR(TheSqlSrvProfilerFileWrite);
  1671     __COUNTER_INCR(TheSqlSrvProfilerFileWrite);
  1609 	__OSTIME_COUNTER(TheOsCallTicks[EOsFileWrite], ::OsCallProfile(dbFile.iIsJournal, EOsFileWrite), aOffset, aAmt, aDbFile, 0);
  1672     __OSTIME_COUNTER(TheOsCallTicks[EOsFileWrite], ::OsCallProfile(dbFile.iIsJournal, EOsFileWrite), aOffset, aAmt, aDbFile, 0);
  1610 	TInt err = KErrAccessDenied;
  1673     err = KErrAccessDenied;
  1611 	if(!dbFile.iReadOnly)
  1674     if(!dbFile.iReadOnly)
  1612 		{
  1675         {
  1613 		TPtrC8 ptr((const TUint8*)aData, aAmt);
  1676         TPtrC8 ptr((const TUint8*)aData, aAmt);
  1614 		err = dbFile.iFileBuf.Write(aOffset, ptr);
  1677         err = dbFile.iFileBuf.Write(aOffset, ptr);
  1615 		}
  1678         }
  1616 	COsLayerData::Instance().SetOsErrorCode(err);
  1679     COsLayerData::Instance().SetOsErrorCode(err);
  1617 	
  1680     
  1618 	const TInt KFreePageCountOffset = 36;//hard-coded constant. SQLite does not offer anything - a constant or #define.
  1681     const TInt KFreePageCountOffset = 36;//hard-coded constant. SQLite does not offer anything - a constant or #define.
  1619 	//The checks in the "if" bellow do:
  1682     //The checks in the "if" bellow do:
  1620 	// - "err == KErrNone" - check the free page count only after a successful "write";
  1683     // - "err == KErrNone" - check the free page count only after a successful "write";
  1621 	// - "aOffset == 0"    - check the free page count only if the write operation affects the system page (at aOffset = 0);
  1684     // - "aOffset == 0"    - check the free page count only if the write operation affects the system page (at aOffset = 0);
  1622 	// - "aAmt >= (KFreePageCountOffset + sizeof(int))" - check the free page count only if the amount of bytes to be written
  1685     // - "aAmt >= (KFreePageCountOffset + sizeof(int))" - check the free page count only if the amount of bytes to be written
  1623 	//						 is more than the offset of the free page counter (othewrise the free page counter is not affected
  1686     //						 is more than the offset of the free page counter (othewrise the free page counter is not affected
  1624 	//						 by this write operation);
  1687     //						 by this write operation);
  1625 	// - "dbFile.iFreePageCallback.IsValid()" - check the free page count only if there is a valid callback;
  1688     // - "dbFile.iFreePageCallback.IsValid()" - check the free page count only if there is a valid callback;
  1626 	if(err == KErrNone  && aOffset == 0 && aAmt >= (KFreePageCountOffset + sizeof(int)) && dbFile.iFreePageCallback.IsValid())
  1689     if(err == KErrNone  && aOffset == 0 && aAmt >= (KFreePageCountOffset + sizeof(int)) && dbFile.iFreePageCallback.IsValid())
  1627 		{
  1690         {
  1628 		const TUint8* ptr = static_cast <const TUint8*> (aData) + KFreePageCountOffset;
  1691         const TUint8* ptr = static_cast <const TUint8*> (aData) + KFreePageCountOffset;
  1629 		TInt freePageCount = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
  1692         TInt freePageCount = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
  1630 		dbFile.iFreePageCallback.CheckAndCallback(freePageCount);
  1693         dbFile.iFreePageCallback.CheckAndCallback(freePageCount);
  1631 		}
  1694         }
  1632 		
       
  1633 	return err == KErrNone ? SQLITE_OK : (err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_FULL);
  1695 	return err == KErrNone ? SQLITE_OK : (err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_FULL);
  1634 	}
  1696 	}
  1635 
  1697 
  1636 /**
  1698 /**
  1637 SQLite OS porting layer API.
  1699 SQLite OS porting layer API.
  2231 
  2293 
  2232 @see COsLayerData::SetOsErrorCode()
  2294 @see COsLayerData::SetOsErrorCode()
  2233 @see TDbFile
  2295 @see TDbFile
  2234 */
  2296 */
  2235 /* static */ int TVfs::Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags)
  2297 /* static */ int TVfs::Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags)
  2236 	{
  2298 	{   
  2237 	SQLUTRACE_PROFILER(aVfs);
  2299     SQLUTRACE_PROFILER(aVfs);
  2238 	__OS_CALL(EOsVfsOpen, 0, 0);
  2300     __OS_CALL(EOsVfsOpen, 0, 0);
  2239 	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsOpen], ::OsCallProfile(EFalse, EOsVfsOpen), 0, 0, aDbFile, aFileName);
  2301     __OSTIME_COUNTER(TheOsCallTicks[EOsVfsOpen], ::OsCallProfile(EFalse, EOsVfsOpen), 0, 0, aDbFile, aFileName);
  2240 	COsLayerData& osLayerData = COsLayerData::Instance();
  2302  
  2241 	TFileName fname;
  2303     COsLayerData& osLayerData = COsLayerData::Instance();
  2242 	if(aFileName && !::ConvertToUnicode(aFileName, fname))
  2304     TFhStrType fhStrType = ENotFhStr;
  2243 		{
  2305     new (aDbFile) TDbFile;
  2244 		osLayerData.SetOsErrorCode(KErrBadName);
  2306     TDbFile& dbFile = ::DbFile(aDbFile);
  2245 		return SQLITE_CANTOPEN;	
  2307 
  2246 		}
  2308     if(!aFileName)
  2247 	SYMBIAN_TRACE_SQL_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileOpen, aDbFile, &fname));
  2309         {  
  2248 	new (aDbFile) TDbFile;
  2310         //It is to create and open a temp file if aFileName is NULL. In this case,
  2249 	TDbFile& dbFile = ::DbFile(aDbFile);
  2311         //we will defer the file creation util it is needed.  
  2250 	TFhStrType fhStrType = aFileName ? ::FhStringProps(aFileName) : ENotFhStr;
  2312     
  2251 	if(aFileName && (aFlags & SQLITE_OPEN_DELETEONCLOSE))
  2313         dbFile.pMethods = &TheFileIoApi;
  2252 		{
  2314         dbFile.iIsFileCreated = EFalse;
  2253 		dbFile.iFullName = fname.Alloc();
  2315         if(aOutFlags)
  2254 		if(!dbFile.iFullName)
  2316             {
  2255 			{
  2317             *aOutFlags = SQLITE_OPEN_READWRITE;
  2256 			osLayerData.SetOsErrorCode(KErrNoMemory);
  2318             }
  2257 			return SQLITE_IOERR_NOMEM;
  2319         return SQLITE_OK;
  2258 			}
  2320         }  
  2259 		}
  2321     
  2260 	TInt recReadBufSize = -1;
  2322     TFileName fname;
  2261 	TInt err = KErrNone;
  2323     if(!::ConvertToUnicode(aFileName, fname))
  2262 	if(fhStrType == EFhMainDbStr)
  2324         {
  2263 		{//Main db file, open from handle
  2325         osLayerData.SetOsErrorCode(KErrBadName);
  2264 		const RMessage2* msg;
  2326         return SQLITE_CANTOPEN;	
  2265 		TBool readOnly;
  2327         }
  2266 		osLayerData.RetrieveAndResetFhData(msg, readOnly);
  2328     SYMBIAN_TRACE_SQL_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileOpen, aDbFile, &fname));
  2267 		err = msg != NULL ? TVfs::DoOpenFromHandle(dbFile, *msg, readOnly) : KErrGeneral;
  2329     fhStrType = ::FhStringProps(aFileName);
  2268 		}
  2330     TInt err = KErrNone;
  2269 	else
  2331     TInt recReadBufSize = -1;
  2270 		{
  2332     if(fhStrType == EFhMainDbStr)
  2271 		if(fhStrType == EFhStr)
  2333         {//Main db file, open from handle
  2272 			{//Not the main db file. Remove invalid characters in the file name
  2334         const RMessage2* msg;
  2273 			::FhConvertToFileName(fname, osLayerData.iSysPrivDir);//If fname does not have a path, iSysPrivDir will be used
  2335         TBool readOnly;
  2274 			}
  2336         osLayerData.RetrieveAndResetFhData(msg, readOnly);
  2275 		TInt fmode = EFileRead;
  2337         err = msg != NULL ? TVfs::DoOpenFromHandle(dbFile, *msg, readOnly) : KErrGeneral;
  2276 		if(aFlags & SQLITE_OPEN_READWRITE)
  2338         }
  2277 			{
  2339     else
  2278 			fmode |= EFileWrite;
  2340         {
  2279 			}
  2341         if(fhStrType == EFhStr)
  2280 		if(aFlags & SQLITE_OPEN_EXCLUSIVE)
  2342             {//Not the main db file. Remove invalid characters in the file name
  2281 			{
  2343             ::FhConvertToFileName(fname, osLayerData.iSysPrivDir);//If fname does not have a path, iSysPrivDir will be used
  2282 			fmode |= EFileShareExclusive;
  2344             }
  2283 			}
  2345         TInt fmode = EFileRead;
  2284 		if(!aFileName)	
  2346         if(aFlags & SQLITE_OPEN_READWRITE)
  2285 			{
  2347             {
  2286 			__FS_CALL(EFsOpFileCreateTemp, 0);
  2348             fmode |= EFileWrite;
  2287 			err = dbFile.iFileBuf.Temp(osLayerData.iFs, osLayerData.iSysPrivDir, fname, fmode);
  2349             }
  2288 			if(err == KErrNone)
  2350         if(aFlags & SQLITE_OPEN_EXCLUSIVE)
  2289 				{
  2351             {
  2290 				dbFile.iFullName = fname.Alloc();
  2352             fmode |= EFileShareExclusive;
  2291 				if(!dbFile.iFullName)
  2353             }
  2292 					{
  2354             err = KErrAccessDenied;
  2293 					err = KErrNoMemory;	
  2355             TInt prevErr = KErrNone;
  2294 					}
  2356             if(aFlags & SQLITE_OPEN_DELETEONCLOSE)
  2295 				}
  2357                 {
  2296 			}
  2358                 fmode |= EDeleteOnClose;
  2297 		else
  2359                 }
  2298 			{
  2360             if(aFlags & SQLITE_OPEN_CREATE)
  2299 			err = KErrAccessDenied;
  2361                 {
  2300 			TInt prevErr = KErrNone;
  2362                 __FS_CALL(EFsOpFileCreate, 0);
  2301 			if(aFlags & SQLITE_OPEN_CREATE)
  2363                 prevErr = err = dbFile.iFileBuf.Create(osLayerData.iFs, fname, fmode);
  2302 				{
  2364                 }
  2303 				__FS_CALL(EFsOpFileCreate, 0);
  2365             if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull)
  2304 				prevErr = err = dbFile.iFileBuf.Create(osLayerData.iFs, fname, fmode);
  2366                 {
  2305 				}
  2367                 __FS_CALL(EFsOpFileOpen, 0);
  2306 			if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull)
  2368                 err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2307 				{
  2369                 
  2308 				__FS_CALL(EFsOpFileOpen, 0);
  2370                 if(err == KErrNone && (aFlags & KJournalFileTypeBitMask))
  2309 				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2371                     {
  2310 				
       
  2311 				if(err == KErrNone && (aFlags & KJournalFileTypeBitMask))
       
  2312 				    {
       
  2313                     err = TVfs::DoFileSizeCorruptionCheck(dbFile, fname, fmode);
  2372                     err = TVfs::DoFileSizeCorruptionCheck(dbFile, fname, fmode);
  2314 				    }
  2373                     }
  2315 				}
  2374                 }
  2316 			if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE))
  2375             if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE))
  2317 				{
  2376                 {
  2318 				aFlags &= ~SQLITE_OPEN_READWRITE;
  2377                 aFlags &= ~SQLITE_OPEN_READWRITE;
  2319 				aFlags |= SQLITE_OPEN_READONLY;
  2378                 aFlags |= SQLITE_OPEN_READONLY;
  2320 				fmode &= ~EFileWrite;
  2379                 fmode &= ~EFileWrite;
  2321 				__FS_CALL(EFsOpFileOpen, 0);
  2380                 __FS_CALL(EFsOpFileOpen, 0);
  2322    				err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2381                 err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  2323 				}
  2382                 }
  2324 			if(err != KErrNone && prevErr == KErrAccessDenied)
  2383             if(err != KErrNone && prevErr == KErrAccessDenied)
  2325 				{
  2384                 {
  2326 				err = KErrAccessDenied;
  2385                 err = KErrAccessDenied;
  2327 				}
  2386                 }
  2328 			}
  2387         }
  2329 		}
  2388     if(err == KErrNone)
  2330 	if(err == KErrNone)
  2389         {
  2331 		{
  2390         err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(dbFile, recReadBufSize);
  2332 		err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(dbFile, recReadBufSize);
  2391         }	
  2333 		}
  2392  	
  2334 	osLayerData.SetOsErrorCode(err);
  2393 	osLayerData.SetOsErrorCode(err);
  2335 	if(err != KErrNone)
  2394 	if(err != KErrNone)
  2336 		{
  2395 		{
  2337 		__FS_CALL(EFsOpFileClose, 0);
  2396 		__FS_CALL(EFsOpFileClose, 0);
  2338 		dbFile.iFileBuf.Close();	
  2397 		dbFile.iFileBuf.Close();	
  2339 		delete dbFile.iFullName;
       
  2340 		dbFile.iFullName = NULL;
       
  2341         if(!aFileName && fname.Length() > 0)
       
  2342             {//temporary file, the error is not KErrNone. Then delete the file (after a successfull 
       
  2343              //temporary file creation there could be a failed memory allocation)
       
  2344             (void)osLayerData.iFs.Delete(fname);
       
  2345             }
       
  2346 		}
  2398 		}
  2347 	else
  2399 	else
  2348 		{
  2400 		{
  2349 		dbFile.pMethods = &TheFileIoApi;
  2401 		dbFile.pMethods = &TheFileIoApi;
  2350 		if(fhStrType != EFhMainDbStr)
  2402 		if(fhStrType != EFhMainDbStr)