34 #include "os.h" |
34 #include "os.h" |
35 #include "os_common.h" |
35 #include "os_common.h" |
36 } |
36 } |
37 #include <e32math.h> |
37 #include <e32math.h> |
38 #include "os_symbian.h" |
38 #include "os_symbian.h" |
39 #include "UTraceSqlite.h" |
39 #include "SqliteUtil.h" |
|
40 #include "OstTraceDefinitions.h" |
|
41 #ifdef OST_TRACE_COMPILER_IN_USE |
|
42 #include "os_symbian_mtTraces.h" |
|
43 #endif |
|
44 #include "SqliteTraceDef.h" |
|
45 |
|
46 //Bit-mask constant. If xOpen()'s "aFlag" parameter contains one of these bits set, then the the file top be |
|
47 //opened or created is a journal file. |
|
48 const TUint KJournalFileTypeBitMask = SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL; |
40 |
49 |
41 #ifdef SQLITE_TEST |
50 #ifdef SQLITE_TEST |
42 |
51 |
43 //Count the number of fullsyncs and normal syncs. This is used to test |
52 //Count the number of fullsyncs and normal syncs. This is used to test |
44 //that syncs and fullsyncs are occuring at the right times. |
53 //that syncs and fullsyncs are occuring at the right times. |
137 */ |
147 */ |
138 sqlite3_mutex::sqlite3_mutex() : |
148 sqlite3_mutex::sqlite3_mutex() : |
139 iRefCount(0), |
149 iRefCount(0), |
140 iOwnerThreadId(KMaxTUint64) |
150 iOwnerThreadId(KMaxTUint64) |
141 { |
151 { |
|
152 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, SQLITE3_MUTEX_SQLITE3_MUTEX, "OS;0x%X;sqlite3_mutex::sqlite3_mutex", (TUint)this)); |
142 } |
153 } |
143 |
154 |
144 /** |
155 /** |
145 Closes the mutex handle. |
156 Closes the mutex handle. |
146 */ |
157 */ |
147 sqlite3_mutex::~sqlite3_mutex() |
158 sqlite3_mutex::~sqlite3_mutex() |
148 { |
159 { |
|
160 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, SQLITE3_MUTEX_SQLITE3_MUTEX2, "OS;0x%X;sqlite3_mutex::~sqlite3_mutex", (TUint)this)); |
149 iMutex.Close(); |
161 iMutex.Close(); |
150 } |
162 } |
151 |
163 |
152 /** |
164 /** |
153 Gives the calling thread an exclusive access to the SQLite resources (global variables, file handles, buffers, cache, etc.). |
165 Gives the calling thread an exclusive access to the SQLite resources (global variables, file handles, buffers, cache, etc.). |
175 @panic SqliteMt 23 Negative mutex lock counter (in debug builds only) |
187 @panic SqliteMt 23 Negative mutex lock counter (in debug builds only) |
176 @panic SqliteMt 24 The mutex has been entered (locked) by a different thread than the current one (in debug builds only) |
188 @panic SqliteMt 24 The mutex has been entered (locked) by a different thread than the current one (in debug builds only) |
177 */ |
189 */ |
178 void sqlite3_mutex::Leave() |
190 void sqlite3_mutex::Leave() |
179 { |
191 { |
180 __ASSERT_DEBUG(iRefCount > 0, User::Panic(KPanicCategory, EPanicMutexLockCounter)); |
192 __ASSERT_DEBUG(iRefCount > 0, __SQLITEPANIC(ESqliteOsPanicMutexLockCounter)); |
181 #ifdef _DEBUG |
193 #ifdef _DEBUG |
182 RThread currThread; |
194 RThread currThread; |
183 __ASSERT_DEBUG(iOwnerThreadId == currThread.Id(), User::Panic(KPanicCategory, EPanicMutexOwner)); |
195 __ASSERT_DEBUG(iOwnerThreadId == currThread.Id(), __SQLITEPANIC(ESqliteOsPanicMutexOwner)); |
184 #endif |
196 #endif |
185 --iRefCount; |
197 --iRefCount; |
186 iMutex.Signal(); |
198 iMutex.Signal(); |
187 } |
199 } |
188 |
200 |
266 @param aType The mutex type: static, fast, recursive |
279 @param aType The mutex type: static, fast, recursive |
267 @return A pointer to the created mutex or NULL if the operation has failed |
280 @return A pointer to the created mutex or NULL if the operation has failed |
268 */ |
281 */ |
269 sqlite3_mutex* TMutexApi::Alloc(int aType) |
282 sqlite3_mutex* TMutexApi::Alloc(int aType) |
270 { |
283 { |
271 SQLUTRACE_PROFILER(0); |
|
272 sqlite3_mutex* mutex = NULL; |
284 sqlite3_mutex* mutex = NULL; |
273 switch(aType) |
285 switch(aType) |
274 { |
286 { |
275 case SQLITE_MUTEX_FAST: |
287 case SQLITE_MUTEX_FAST: |
276 case SQLITE_MUTEX_RECURSIVE: |
288 case SQLITE_MUTEX_RECURSIVE: |
279 default: |
291 default: |
280 mutex = ::StaticMutex(aType - 2);//"aType - 2" because the first SQLITE_MUTEX_STATIC_<type> mutex definition |
292 mutex = ::StaticMutex(aType - 2);//"aType - 2" because the first SQLITE_MUTEX_STATIC_<type> mutex definition |
281 //value is 2 (SQLITE_MUTEX_FAST is 0, SQLITE_MUTEX_RECURSIVE is 1). |
293 //value is 2 (SQLITE_MUTEX_FAST is 0, SQLITE_MUTEX_RECURSIVE is 1). |
282 break; |
294 break; |
283 } |
295 } |
|
296 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TMUTEXAPI_ALLOC, "OS;0;TMutexApi::Alloc;aType=%d;mutex=0x%X", aType, (TUint)mutex)); |
284 return mutex; |
297 return mutex; |
285 } |
298 } |
286 |
299 |
287 /** |
300 /** |
288 Destroys a mutex, created previously by a call to TMutexApi::Alloc(). |
301 Destroys a mutex, created previously by a call to TMutexApi::Alloc(). |
289 @param aMutex Pointer to the mutex object that has to be destroyed |
302 @param aMutex Pointer to the mutex object that has to be destroyed |
290 */ |
303 */ |
291 void TMutexApi::Free(sqlite3_mutex* aMutex) |
304 void TMutexApi::Free(sqlite3_mutex* aMutex) |
292 { |
305 { |
293 SQLUTRACE_PROFILER(0); |
306 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TMUTEXAPI_FREE, "OS;0;TMutexApi::Free;mutex=0x%X", (TUint)aMutex)); |
294 delete aMutex; |
307 delete aMutex; |
295 } |
308 } |
296 |
309 |
297 /** |
310 /** |
298 Locks the mutex. |
311 Locks the mutex. |
372 /** |
380 /** |
373 Initializes the OS porting layer global data. |
381 Initializes the OS porting layer global data. |
374 */ |
382 */ |
375 extern "C" SQLITE_EXPORT int sqlite3_os_init(void) |
383 extern "C" SQLITE_EXPORT int sqlite3_os_init(void) |
376 { |
384 { |
377 return sqlite3_vfs_register(VfsApi(), 1); |
385 TInt err = sqlite3_vfs_register(VfsApi(), 1); |
|
386 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, SQLITE3_OS_INIT, "OS;0;sqlite3_os_init;err=%d", err)); |
|
387 return err; |
378 } |
388 } |
379 |
389 |
380 /** |
390 /** |
381 Destroys the OS porting layer global data. |
391 Destroys the OS porting layer global data. |
382 */ |
392 */ |
383 extern "C" SQLITE_EXPORT int sqlite3_os_end(void) |
393 extern "C" SQLITE_EXPORT int sqlite3_os_end(void) |
384 { |
394 { |
385 return sqlite3_vfs_unregister(VfsApi()); |
395 TInt err = sqlite3_vfs_unregister(VfsApi()); |
|
396 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, SQLITE3_OS_END, "OS;0;sqlite3_os_end;err=%d", err)); |
|
397 return err; |
386 } |
398 } |
387 |
399 |
388 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
400 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
389 ////////////////////////// TheFileIoApi ///////////////////////////////////////////////////////////////////////////////////// |
401 ////////////////////////// TheFileIoApi ///////////////////////////////////////////////////////////////////////////////////// |
390 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
402 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
561 |
574 |
562 @see TDbFile |
575 @see TDbFile |
563 */ |
576 */ |
564 /* static */ int TFileIo::Close(sqlite3_file* aDbFile) |
577 /* static */ int TFileIo::Close(sqlite3_file* aDbFile) |
565 { |
578 { |
566 SQLUTRACE_PROFILER(aDbFile); |
|
567 TDbFile& dbFile = ::DbFile(aDbFile); |
579 TDbFile& dbFile = ::DbFile(aDbFile); |
|
580 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_CLOSE1, "OS;0x%X;TFileIo::Close", (TUint)&dbFile)); |
568 dbFile.iFileBuf.Close(); |
581 dbFile.iFileBuf.Close(); |
569 if(dbFile.iFullName) |
582 if(dbFile.iFullName) |
570 {//"iFullName" will not be NULL only when TVfs::Open() is called with SQLITE_OPEN_DELETEONCLOSE flag. |
583 {//"iFullName" will not be NULL only when TVfs::Open() is called with SQLITE_OPEN_DELETEONCLOSE flag. |
571 //That means - SQlite expects the file to be deleted after the file close operation. |
584 //That means - SQlite expects the file to be deleted after the file close operation. |
572 (void)TStaticFs::Fs().Delete(*dbFile.iFullName); |
585 __SQLITETRACE_OSEXPR(TInt err = ) TStaticFs::Fs().Delete(*dbFile.iFullName); |
|
586 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_CLOSE2, "OS;0x%X;TFileIo::Close;delete fileName=%S;err=%d", (TUint)&dbFile, __SQLITEPRNSTR(*dbFile.iFullName), err)); |
573 delete dbFile.iFullName; |
587 delete dbFile.iFullName; |
574 dbFile.iFullName = NULL; |
588 dbFile.iFullName = NULL; |
575 } |
589 } |
576 OpenCounter(-1); |
590 OpenCounter(-1); |
577 return SQLITE_OK; |
591 return SQLITE_OK; |
596 |
610 |
597 @see TDbFile |
611 @see TDbFile |
598 */ |
612 */ |
599 /* static */ int TFileIo::Read(sqlite3_file* aDbFile, void* aBuf, int aAmt, sqlite3_int64 aOffset) |
613 /* static */ int TFileIo::Read(sqlite3_file* aDbFile, void* aBuf, int aAmt, sqlite3_int64 aOffset) |
600 { |
614 { |
601 SQLUTRACE_PROFILER(aDbFile); |
|
602 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileRead, aAmt, aOffset)); |
|
603 SimulateIOError(return SQLITE_IOERR_READ); |
615 SimulateIOError(return SQLITE_IOERR_READ); |
604 TDbFile& dbFile = ::DbFile(aDbFile); |
616 TDbFile& dbFile = ::DbFile(aDbFile); |
|
617 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_READ_ENTRY, "OS-Entry;0x%X;TFileIo::Read;aAmt=%d;aOffset=%lld", (TUint)&dbFile, aAmt, aOffset)); |
605 TPtr8 ptr((TUint8*)aBuf, 0, aAmt); |
618 TPtr8 ptr((TUint8*)aBuf, 0, aAmt); |
606 TInt err = dbFile.iFileBuf.Read(aOffset, ptr); |
619 TInt err = dbFile.iFileBuf.Read(aOffset, ptr); |
607 TInt cnt = ptr.Length(); |
620 TInt cnt = ptr.Length(); |
608 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_READ); |
621 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_READ); |
609 if(cnt != aAmt && (sqliteErr == SQLITE_OK || sqliteErr == SQLITE_IOERR_SHORT_READ)) |
622 if(cnt != aAmt && (sqliteErr == SQLITE_OK || sqliteErr == SQLITE_IOERR_SHORT_READ)) |
610 { |
623 { |
611 Mem::FillZ(static_cast <TUint8*> (aBuf) + cnt, aAmt - cnt); |
624 Mem::FillZ(static_cast <TUint8*> (aBuf) + cnt, aAmt - cnt); |
612 sqliteErr = SQLITE_IOERR_SHORT_READ; |
625 sqliteErr = SQLITE_IOERR_SHORT_READ; |
613 } |
626 } |
|
627 SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TFILEIO_READ_EXIT, "OS-Exit;0x%X;TFileIo::Read;cnt=%d;err=%d;sqliteErr=%d", (TUint)&dbFile, cnt, err, sqliteErr)); |
614 return sqliteErr; |
628 return sqliteErr; |
615 } |
629 } |
616 |
630 |
617 /** |
631 /** |
618 SQLite OS porting layer API. |
632 SQLite OS porting layer API. |
632 |
646 |
633 @see TDbFile |
647 @see TDbFile |
634 */ |
648 */ |
635 /* static */ int TFileIo::Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset) |
649 /* static */ int TFileIo::Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset) |
636 { |
650 { |
637 SQLUTRACE_PROFILER(aDbFile); |
|
638 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileWrite, aAmt, aOffset)); |
|
639 SimulateIOError(return SQLITE_IOERR_WRITE); |
651 SimulateIOError(return SQLITE_IOERR_WRITE); |
640 SimulateDiskfullError(return SQLITE_FULL); |
652 SimulateDiskfullError(return SQLITE_FULL); |
641 TDbFile& dbFile = ::DbFile(aDbFile); |
653 TDbFile& dbFile = ::DbFile(aDbFile); |
|
654 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_WRITE_ENTRY, "OS-Entry;0x%X;TFileIo::Write;aAmt=%d;aOffset=%lld", (TUint)&dbFile, aAmt, aOffset)); |
642 TInt err = KErrAccessDenied; |
655 TInt err = KErrAccessDenied; |
643 if(!dbFile.iReadOnly) |
656 if(!dbFile.iReadOnly) |
644 { |
657 { |
645 TPtrC8 ptr((const TUint8*)aData, aAmt); |
658 TPtrC8 ptr((const TUint8*)aData, aAmt); |
646 err = dbFile.iFileBuf.Write(aOffset, ptr); |
659 err = dbFile.iFileBuf.Write(aOffset, ptr); |
647 } |
660 } |
648 return ::Os2SqliteErr(err, SQLITE_IOERR_WRITE); |
661 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_WRITE); |
|
662 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_WRITE_EXIT, "OS-Exit;0x%X;TFileIo::Write;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr)); |
|
663 return sqliteErr; |
649 } |
664 } |
650 |
665 |
651 /** |
666 /** |
652 SQLite OS porting layer API. |
667 SQLite OS porting layer API. |
653 |
668 |
664 |
679 |
665 @see TDbFile |
680 @see TDbFile |
666 */ |
681 */ |
667 /* static */ int TFileIo::Truncate(sqlite3_file* aDbFile, sqlite3_int64 aLength) |
682 /* static */ int TFileIo::Truncate(sqlite3_file* aDbFile, sqlite3_int64 aLength) |
668 { |
683 { |
669 SQLUTRACE_PROFILER(aDbFile); |
|
670 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileTruncate, aLength)); |
|
671 SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
684 SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
672 TDbFile& dbFile = ::DbFile(aDbFile); |
685 TDbFile& dbFile = ::DbFile(aDbFile); |
|
686 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_TRUNCATE_ENTRY, "OS-Entry;0x%X;TFileIo::Truncate;aLength=%lld", (TUint)&dbFile, aLength)); |
673 TInt err = KErrAccessDenied; |
687 TInt err = KErrAccessDenied; |
674 if(!dbFile.iReadOnly) |
688 if(!dbFile.iReadOnly) |
675 { |
689 { |
676 err = dbFile.iFileBuf.SetSize(aLength); |
690 err = dbFile.iFileBuf.SetSize(aLength); |
677 } |
691 } |
678 return ::Os2SqliteErr(err, SQLITE_IOERR_TRUNCATE); |
692 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_TRUNCATE); |
|
693 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_TRUNCATE_EXIT, "OS-Exit;0x%X;TFileIo::Truncate;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr)); |
|
694 return sqliteErr; |
679 } |
695 } |
680 |
696 |
681 /** |
697 /** |
682 SQLite OS porting layer API. |
698 SQLite OS porting layer API. |
683 |
699 |
694 |
710 |
695 @see TDbFile |
711 @see TDbFile |
696 */ |
712 */ |
697 /* static */int TFileIo::Sync(sqlite3_file* aDbFile, int aFlags) |
713 /* static */int TFileIo::Sync(sqlite3_file* aDbFile, int aFlags) |
698 { |
714 { |
699 SQLUTRACE_PROFILER(aDbFile); |
|
700 SimulateIOError(return SQLITE_IOERR_FSYNC); |
715 SimulateIOError(return SQLITE_IOERR_FSYNC); |
701 TDbFile& dbFile = ::DbFile(aDbFile); |
716 TDbFile& dbFile = ::DbFile(aDbFile); |
|
717 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_SYNC_ENTRY, "OS-Entry;0x%X;TFileIo::Sync", (TUint)&dbFile)); |
702 #ifdef SQLITE_TEST |
718 #ifdef SQLITE_TEST |
703 if(aFlags & SQLITE_SYNC_FULL) |
719 if(aFlags & SQLITE_SYNC_FULL) |
704 { |
720 { |
705 sqlite3_fullsync_count++; |
721 sqlite3_fullsync_count++; |
706 } |
722 } |
730 |
748 |
731 @see TDbFile |
749 @see TDbFile |
732 */ |
750 */ |
733 /* static */ int TFileIo::FileSize(sqlite3_file* aDbFile, sqlite3_int64* aSize) |
751 /* static */ int TFileIo::FileSize(sqlite3_file* aDbFile, sqlite3_int64* aSize) |
734 { |
752 { |
735 SQLUTRACE_PROFILER(aDbFile); |
|
736 SimulateIOError(return SQLITE_IOERR_FSTAT); |
753 SimulateIOError(return SQLITE_IOERR_FSTAT); |
737 TDbFile& dbFile = ::DbFile(aDbFile); |
754 TDbFile& dbFile = ::DbFile(aDbFile); |
|
755 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_FILESIZE_ENTRY, "OS-Entry;0x%X;TFileIo::FileSize", (TUint)&dbFile)); |
738 TInt err = dbFile.iFileBuf.Size(*aSize); |
756 TInt err = dbFile.iFileBuf.Size(*aSize); |
739 return ::Os2SqliteErr(err, SQLITE_IOERR_FSTAT); |
757 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_FSTAT); |
|
758 SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TFILEIO_FILESIZE_EXIT, "OS-Exit;0x%X;TFileIo::FileSize;aSize=%lld;err=%d;sqliteErr=%d", (TUint)&dbFile, *aSize, err, sqliteErr)); |
|
759 return sqliteErr; |
740 } |
760 } |
741 |
761 |
742 /** |
762 /** |
743 This function is called when SQLite needs to obtain a read lock. This is done by generating a |
763 This function is called when SQLite needs to obtain a read lock. This is done by generating a |
744 random file position within the first page beyond the first Gb of the file and locking a single byte there. |
764 random file position within the first page beyond the first Gb of the file and locking a single byte there. |
830 |
853 |
831 @see TDbFile |
854 @see TDbFile |
832 */ |
855 */ |
833 /* static */ int TFileIo::Lock(sqlite3_file* aDbFile, int aLockType) |
856 /* static */ int TFileIo::Lock(sqlite3_file* aDbFile, int aLockType) |
834 { |
857 { |
835 SQLUTRACE_PROFILER(aDbFile); |
|
836 TDbFile& dbFile = ::DbFile(aDbFile); |
858 TDbFile& dbFile = ::DbFile(aDbFile); |
837 //If there is already a lock of this type or more restrictive on the aDbFile, then - do nothing. |
859 //If there is already a lock of this type or more restrictive on the aDbFile, then - do nothing. |
838 if(dbFile.iLockType >= aLockType) |
860 if(dbFile.iLockType >= aLockType) |
839 { |
861 { |
|
862 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_LOCK1, "OS;0x%X;TFileIo::Lock;dbFile.iLockType=%d;aLockType=%d", (TUint)&dbFile, dbFile.iLockType, aLockType)); |
840 return SQLITE_OK; |
863 return SQLITE_OK; |
841 } |
864 } |
842 |
865 |
843 //The file flushing here must be done in order to get the file buffer object content (iFileBuf data member)) |
866 //The file flushing here must be done in order to get the file buffer object content (iFileBuf data member)) |
844 //synchronised with the database file content (the database file content may get modified by a different connection |
867 //synchronised with the database file content (the database file content may get modified by a different connection |
846 if(aLockType == SQLITE_LOCK_SHARED && !dbFile.iReadOnly) |
869 if(aLockType == SQLITE_LOCK_SHARED && !dbFile.iReadOnly) |
847 { |
870 { |
848 TInt err = dbFile.iFileBuf.Flush(ETrue); |
871 TInt err = dbFile.iFileBuf.Flush(ETrue); |
849 if(err != KErrNone) |
872 if(err != KErrNone) |
850 { |
873 { |
|
874 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_LOCK2, "OS;0x%X;TFileIo::Lock;iFileBuf.Flush() failed, err=%d", (TUint)&dbFile, err)); |
851 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
875 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
852 } |
876 } |
853 } |
877 } |
854 |
878 |
855 //Make sure the locking sequence is correct |
879 //Make sure the locking sequence is correct |
856 __ASSERT_DEBUG(dbFile.iLockType != SQLITE_LOCK_NONE || aLockType == SQLITE_LOCK_SHARED, User::Panic(KPanicCategory, EPanicInvalidLock)); |
880 __ASSERT_DEBUG(dbFile.iLockType != SQLITE_LOCK_NONE || aLockType == SQLITE_LOCK_SHARED, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
857 __ASSERT_DEBUG(aLockType != SQLITE_LOCK_PENDING, User::Panic(KPanicCategory, EPanicInvalidLock)); |
881 __ASSERT_DEBUG(aLockType != SQLITE_LOCK_PENDING, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
858 __ASSERT_DEBUG(aLockType != SQLITE_LOCK_RESERVED || dbFile.iLockType == SQLITE_LOCK_SHARED, User::Panic(KPanicCategory, EPanicInvalidLock)); |
882 __ASSERT_DEBUG(aLockType != SQLITE_LOCK_RESERVED || dbFile.iLockType == SQLITE_LOCK_SHARED, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
859 |
883 |
860 TInt rc = SQLITE_OK; //Return code from subroutines |
884 TInt rc = SQLITE_OK; //Return code from subroutines |
861 TBool locked = ETrue; //Result of a file lock call (the default value means: "lock accuired") |
885 TBool locked = ETrue; //Result of a file lock call (the default value means: "lock accuired") |
862 TInt newLockType = -1; //Set dbFile.iLockType to this value before exiting |
886 TInt newLockType = -1; //Set dbFile.iLockType to this value before exiting |
863 TBool gotPendingLock = EFalse;//True if we acquired a SQLITE_LOCK_PENDING lock this time |
887 TBool gotPendingLock = EFalse;//True if we acquired a SQLITE_LOCK_PENDING lock this time |
890 } |
914 } |
891 |
915 |
892 //Acquire a shared lock |
916 //Acquire a shared lock |
893 if(aLockType == SQLITE_LOCK_SHARED && locked) |
917 if(aLockType == SQLITE_LOCK_SHARED && locked) |
894 { |
918 { |
895 __ASSERT_DEBUG(dbFile.iLockType == SQLITE_LOCK_NONE, User::Panic(KPanicCategory, EPanicInvalidLock)); |
919 __ASSERT_DEBUG(dbFile.iLockType == SQLITE_LOCK_NONE, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
896 TInt err = TFileIo::GetReadLock(dbFile); |
920 TInt err = TFileIo::GetReadLock(dbFile); |
897 if(err != KErrNone && err != KErrLocked) |
921 if(err != KErrNone && err != KErrLocked) |
898 { |
922 { |
|
923 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_LOCK3, "OS;0x%X;TFileIo::Lock;TFileIo::GetReadLock() failed, err=%d", (TUint)&dbFile, err)); |
899 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
924 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
900 } |
925 } |
901 locked = (err == KErrNone); |
926 locked = (err == KErrNone); |
902 if(locked) |
927 if(locked) |
903 { |
928 { |
906 } |
931 } |
907 |
932 |
908 //Acquire a RESERVED lock |
933 //Acquire a RESERVED lock |
909 if(aLockType == SQLITE_LOCK_RESERVED && locked) |
934 if(aLockType == SQLITE_LOCK_RESERVED && locked) |
910 { |
935 { |
911 __ASSERT_DEBUG(dbFile.iLockType == SQLITE_LOCK_SHARED, User::Panic(KPanicCategory, EPanicInvalidLock)); |
936 __ASSERT_DEBUG(dbFile.iLockType == SQLITE_LOCK_SHARED, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
912 TInt err = dbFile.iFileBuf.Lock(RESERVED_BYTE, 1); |
937 TInt err = dbFile.iFileBuf.Lock(RESERVED_BYTE, 1); |
913 if(err != KErrNone && err != KErrLocked) |
938 if(err != KErrNone && err != KErrLocked) |
914 { |
939 { |
|
940 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_LOCK4, "OS;0x%X;TFileIo::Lock;iFileBuf.Lock() failed, err=%d", (TUint)&dbFile, err)); |
915 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
941 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
916 } |
942 } |
917 locked = (err == KErrNone); |
943 locked = (err == KErrNone); |
918 if(locked) |
944 if(locked) |
919 { |
945 { |
929 } |
955 } |
930 |
956 |
931 //Acquire an EXCLUSIVE lock |
957 //Acquire an EXCLUSIVE lock |
932 if(aLockType == SQLITE_LOCK_EXCLUSIVE && locked) |
958 if(aLockType == SQLITE_LOCK_EXCLUSIVE && locked) |
933 { |
959 { |
934 __ASSERT_DEBUG(dbFile.iLockType >= SQLITE_LOCK_SHARED, User::Panic(KPanicCategory, EPanicInvalidLock)); |
960 __ASSERT_DEBUG(dbFile.iLockType >= SQLITE_LOCK_SHARED, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
935 (void)TFileIo::UnlockReadLock(dbFile); |
961 (void)TFileIo::UnlockReadLock(dbFile); |
936 TInt err = dbFile.iFileBuf.Lock(SHARED_FIRST, SHARED_SIZE); |
962 TInt err = dbFile.iFileBuf.Lock(SHARED_FIRST, SHARED_SIZE); |
937 if(err != KErrNone && err != KErrLocked) |
963 if(err != KErrNone && err != KErrLocked) |
938 { |
964 { |
|
965 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_LOCK5, "OS;0x%X;TFileIo::Lock;iFileBuf.Lock()-2 failed, err=%d", (TUint)&dbFile, err)); |
939 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
966 return ::Os2SqliteErr(err, SQLITE_IOERR_LOCK); |
940 } |
967 } |
941 locked = (err == KErrNone); |
968 locked = (err == KErrNone); |
942 if(locked) |
969 if(locked) |
943 { |
970 { |
947 |
974 |
948 // If we are holding a PENDING lock that ought to be released, then |
975 // If we are holding a PENDING lock that ought to be released, then |
949 // release it now. |
976 // release it now. |
950 if(gotPendingLock && aLockType == SQLITE_LOCK_SHARED) |
977 if(gotPendingLock && aLockType == SQLITE_LOCK_SHARED) |
951 { |
978 { |
952 (void)dbFile.iFileBuf.UnLock(PENDING_BYTE, 1); |
979 __SQLITETRACE_OSEXPR(TInt err =) dbFile.iFileBuf.UnLock(PENDING_BYTE, 1); |
|
980 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_LOCK6, "OS;0x%X;TFileIo::Lock;iFileBuf.UnLock()=%d", (TUint)&dbFile, err)); |
953 } |
981 } |
954 |
982 |
955 // Update the state of the lock has held in the file descriptor then |
983 // Update the state of the lock has held in the file descriptor then |
956 // return the appropriate result code. |
984 // return the appropriate result code. |
957 rc = locked ? SQLITE_OK : SQLITE_BUSY; |
985 rc = locked ? SQLITE_OK : SQLITE_BUSY; |
958 dbFile.iLockType = newLockType; |
986 dbFile.iLockType = newLockType; |
|
987 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_LOCK7, "OS;0x%X;TFileIo::Lock;rc=%d;newLockType=%d", (TUint)&dbFile, rc, newLockType)); |
959 return rc; |
988 return rc; |
960 } |
989 } |
961 |
990 |
962 /** |
991 /** |
963 SQLite OS porting layer API. |
992 SQLite OS porting layer API. |
984 |
1013 |
985 @see TDbFile |
1014 @see TDbFile |
986 */ |
1015 */ |
987 /* static */ int TFileIo::Unlock(sqlite3_file* aDbFile, int aLockType) |
1016 /* static */ int TFileIo::Unlock(sqlite3_file* aDbFile, int aLockType) |
988 { |
1017 { |
989 __ASSERT_DEBUG(aLockType <= SQLITE_LOCK_SHARED, User::Panic(KPanicCategory, EPanicInvalidLock)); |
1018 __ASSERT_DEBUG(aLockType <= SQLITE_LOCK_SHARED, __SQLITEPANIC2(ESqliteOsPanicInvalidLock)); |
990 |
1019 |
991 SQLUTRACE_PROFILER(aDbFile); |
|
992 TDbFile& dbFile = ::DbFile(aDbFile); |
1020 TDbFile& dbFile = ::DbFile(aDbFile); |
993 TInt rc = SQLITE_OK; |
1021 TInt rc = SQLITE_OK; |
994 TInt currLockType = dbFile.iLockType; |
1022 TInt currLockType = dbFile.iLockType; |
995 |
1023 |
996 if(currLockType >= SQLITE_LOCK_EXCLUSIVE) |
1024 if(currLockType >= SQLITE_LOCK_EXCLUSIVE) |
997 { |
1025 { |
998 (void)dbFile.iFileBuf.UnLock(SHARED_FIRST, SHARED_SIZE); |
1026 __SQLITETRACE_OSEXPR(TInt err2 =) dbFile.iFileBuf.UnLock(SHARED_FIRST, SHARED_SIZE); |
|
1027 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_UNLOCK1, "OS;0x%X;TFileIo::Unlock;iFileBuf.UnLock()=%d", (TUint)&dbFile, err2)); |
999 if(aLockType == SQLITE_LOCK_SHARED) |
1028 if(aLockType == SQLITE_LOCK_SHARED) |
1000 { |
1029 { |
1001 TInt err = TFileIo::GetReadLock(dbFile); |
1030 TInt err = TFileIo::GetReadLock(dbFile); |
1002 if(err != KErrNone && err != KErrLocked) |
1031 if(err != KErrNone && err != KErrLocked) |
1003 { |
1032 { |
|
1033 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_UNLOCK2, "OS;0x%X;TFileIo::Unlock;TFileIo::GetReadLock() failed, err=%d", (TUint)&dbFile, err)); |
1004 return ::Os2SqliteErr(err, SQLITE_IOERR_UNLOCK); |
1034 return ::Os2SqliteErr(err, SQLITE_IOERR_UNLOCK); |
1005 } |
1035 } |
1006 if(err == KErrLocked) |
1036 if(err == KErrLocked) |
1007 { |
1037 { |
1008 //This should never happen. We should always be able to reacquire the read lock |
1038 //This should never happen. We should always be able to reacquire the read lock |
1010 } |
1040 } |
1011 } |
1041 } |
1012 } |
1042 } |
1013 if(currLockType >= SQLITE_LOCK_RESERVED) |
1043 if(currLockType >= SQLITE_LOCK_RESERVED) |
1014 { |
1044 { |
1015 (void)dbFile.iFileBuf.UnLock(RESERVED_BYTE, 1); |
1045 __SQLITETRACE_OSEXPR(TInt err2 =) dbFile.iFileBuf.UnLock(RESERVED_BYTE, 1); |
|
1046 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_UNLOCK3, "OS;0x%X;TFileIo::Unlock;iFileBuf.UnLock()-2=%d", (TUint)&dbFile, err2)); |
1016 } |
1047 } |
1017 if(aLockType == SQLITE_LOCK_NONE && currLockType >= SQLITE_LOCK_SHARED) |
1048 if(aLockType == SQLITE_LOCK_NONE && currLockType >= SQLITE_LOCK_SHARED) |
1018 { |
1049 { |
1019 (void)TFileIo::UnlockReadLock(dbFile); |
1050 __SQLITETRACE_OSEXPR(TInt err2 =) TFileIo::UnlockReadLock(dbFile); |
|
1051 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_UNLOCK4, "OS;0x%X;TFileIo::Unlock;TFileIo::UnlockReadLock()=%d", (TUint)&dbFile, err2)); |
1020 } |
1052 } |
1021 if(currLockType>= SQLITE_LOCK_PENDING) |
1053 if(currLockType>= SQLITE_LOCK_PENDING) |
1022 { |
1054 { |
1023 (void)dbFile.iFileBuf.UnLock(PENDING_BYTE, 1); |
1055 __SQLITETRACE_OSEXPR(TInt err2 =) dbFile.iFileBuf.UnLock(PENDING_BYTE, 1); |
|
1056 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_UNLOCK5, "OS;0x%X;TFileIo::Unlock;iFileBuf.UnLock()-3=%d", (TUint)&dbFile, err2)); |
1024 } |
1057 } |
1025 |
1058 |
1026 dbFile.iLockType = aLockType; |
1059 dbFile.iLockType = aLockType; |
|
1060 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_UNLOCK6, "OS;0x%X;TFileIo::Unlock;rc=%d;newLockType=%d", (TUint)&dbFile, rc, aLockType)); |
1027 return rc; |
1061 return rc; |
1028 } |
1062 } |
1029 |
1063 |
1030 /** |
1064 /** |
1031 SQLite OS porting layer API. |
1065 SQLite OS porting layer API. |
1056 else |
1089 else |
1057 { |
1090 { |
1058 TInt err = dbFile.iFileBuf.Lock(RESERVED_BYTE, 1); |
1091 TInt err = dbFile.iFileBuf.Lock(RESERVED_BYTE, 1); |
1059 if(err != KErrNone && err != KErrLocked) |
1092 if(err != KErrNone && err != KErrLocked) |
1060 { |
1093 { |
|
1094 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_CHECKRESERVEDLOCK1, "OS;0x%X;TFileIo::CheckReservedLock;iFileBuf.Lock(), err=%d", (TUint)&dbFile, err)); |
1061 return ::Os2SqliteErr(err, SQLITE_IOERR_CHECKRESERVEDLOCK); |
1095 return ::Os2SqliteErr(err, SQLITE_IOERR_CHECKRESERVEDLOCK); |
1062 } |
1096 } |
1063 rc = (err == KErrNone); |
1097 rc = (err == KErrNone); |
1064 if(rc) //non-zero rc means: the lock has been successful (there wasn't a reserved lock on this file) |
1098 if(rc) //non-zero rc means: the lock has been successful (there wasn't a reserved lock on this file) |
1065 { |
1099 { |
1066 (void)dbFile.iFileBuf.UnLock(RESERVED_BYTE, 1); |
1100 __SQLITETRACE_OSEXPR(TInt err2 =) dbFile.iFileBuf.UnLock(RESERVED_BYTE, 1); |
|
1101 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_CHECKRESERVEDLOCK2, "OS;0x%X;TFileIo::CheckReservedLock;iFileBuf.UnLock()=%d", (TUint)&dbFile, err2)); |
1067 } |
1102 } |
1068 rc = !rc; |
1103 rc = !rc; |
1069 } |
1104 } |
1070 *aResOut = rc; |
1105 *aResOut = rc; |
|
1106 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_CHECKRESERVEDLOCK3, "OS;0x%X;TFileIo::CheckReservedLock;rc=%d", (TUint)&dbFile, rc)); |
1071 return SQLITE_OK; |
1107 return SQLITE_OK; |
1072 } |
1108 } |
1073 |
1109 |
1074 /** |
1110 /** |
1075 SQLite OS porting layer API. |
1111 SQLite OS porting layer API. |
1090 |
1126 |
1091 @see TDbFile |
1127 @see TDbFile |
1092 */ |
1128 */ |
1093 /* static */ int TFileIo::FileControl(sqlite3_file* aDbFile, int aOp, void* aArg) |
1129 /* static */ int TFileIo::FileControl(sqlite3_file* aDbFile, int aOp, void* aArg) |
1094 { |
1130 { |
1095 SQLUTRACE_PROFILER(aDbFile); |
|
1096 TDbFile& dbFile = ::DbFile(aDbFile); |
1131 TDbFile& dbFile = ::DbFile(aDbFile); |
1097 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileFileCtr, aOp, dbFile.iFullName)); |
|
1098 TInt err = KErrNone; |
1132 TInt err = KErrNone; |
1099 switch(aOp) |
1133 switch(aOp) |
1100 { |
1134 { |
1101 case SQLITE_FCNTL_LOCKSTATE: |
1135 case SQLITE_FCNTL_LOCKSTATE: |
1102 *(int*)aArg = dbFile.iLockType; |
1136 *(int*)aArg = dbFile.iLockType; |
1103 break; |
1137 break; |
1104 default: |
1138 default: |
1105 err = KErrArgument; |
1139 err = KErrArgument; |
1106 break; |
1140 break; |
1107 } |
1141 } |
1108 return err == KErrNone ? SQLITE_OK : SQLITE_ERROR; |
1142 TInt sqliteErr = err == KErrNone ? SQLITE_OK : SQLITE_ERROR; |
|
1143 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_FILECONTROL, "OS;0x%X;TFileIo::FileControl;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr)); |
|
1144 return sqliteErr; |
1109 } |
1145 } |
1110 |
1146 |
1111 /** |
1147 /** |
1112 SQLite OS porting layer API. |
1148 SQLite OS porting layer API. |
1113 |
1149 |
1125 @see TDbFile |
1161 @see TDbFile |
1126 @see TVfs::Open() |
1162 @see TVfs::Open() |
1127 */ |
1163 */ |
1128 /* static */ int TFileIo::SectorSize(sqlite3_file* aDbFile) |
1164 /* static */ int TFileIo::SectorSize(sqlite3_file* aDbFile) |
1129 { |
1165 { |
1130 SQLUTRACE_PROFILER(aDbFile); |
|
1131 TDbFile& dbFile = ::DbFile(aDbFile); |
1166 TDbFile& dbFile = ::DbFile(aDbFile); |
1132 __ASSERT_DEBUG(dbFile.iSectorSize > 0, User::Panic(KPanicCategory, EPanicInternalError)); |
1167 __ASSERT_DEBUG(dbFile.iSectorSize > 0, __SQLITEPANIC2(ESqliteOsPanicInternalError)); |
1133 if(dbFile.iSectorSize > 0) |
1168 if(dbFile.iSectorSize > 0) |
1134 { |
1169 { |
1135 return dbFile.iSectorSize; |
1170 return dbFile.iSectorSize; |
1136 } |
1171 } |
1137 return SQLITE_DEFAULT_SECTOR_SIZE; |
1172 return SQLITE_DEFAULT_SECTOR_SIZE; |
1304 @see TFileIo::DeviceCharacteristics() |
1340 @see TFileIo::DeviceCharacteristics() |
1305 @see TFileIo::SectorSize() |
1341 @see TFileIo::SectorSize() |
1306 */ |
1342 */ |
1307 /* static */ TInt TVfs::DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize) |
1343 /* static */ TInt TVfs::DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize) |
1308 { |
1344 { |
1309 __ASSERT_DEBUG(aDbFile.iDeviceCharacteristics < 0, User::Panic(KPanicCategory, EPanicInternalError)); |
1345 __ASSERT_DEBUG(aDbFile.iDeviceCharacteristics < 0, __SQLITEPANIC2(ESqliteOsPanicInternalError)); |
1310 __ASSERT_DEBUG(aDbFile.iSectorSize <= 0, User::Panic(KPanicCategory, EPanicInternalError)); |
1346 __ASSERT_DEBUG(aDbFile.iSectorSize <= 0, __SQLITEPANIC2(ESqliteOsPanicInternalError)); |
1311 TInt driveNo; |
1347 TInt driveNo; |
1312 TDriveInfo driveInfo; |
1348 TDriveInfo driveInfo; |
1313 TInt err = aDbFile.iFileBuf.Drive(driveNo, driveInfo); |
1349 TInt err = aDbFile.iFileBuf.Drive(driveNo, driveInfo); |
1314 if(err != KErrNone) |
1350 if(err != KErrNone) |
1315 { |
1351 { |
1322 return err; |
1358 return err; |
1323 } |
1359 } |
1324 aDbFile.iDeviceCharacteristics = TVfs::DoGetDeviceCharacteristics(driveInfo, volumeInfo); |
1360 aDbFile.iDeviceCharacteristics = TVfs::DoGetDeviceCharacteristics(driveInfo, volumeInfo); |
1325 aDbFile.iSectorSize = TVfs::DoGetSectorSize(driveInfo, volumeInfo); |
1361 aDbFile.iSectorSize = TVfs::DoGetSectorSize(driveInfo, volumeInfo); |
1326 aRecReadBufSize = volumeInfo.iRecReadBufSize; |
1362 aRecReadBufSize = volumeInfo.iRecReadBufSize; |
|
1363 SQLITE_TRACE_OS(OstTraceExt5(TRACE_INTERNALS, TVFS_DOGETGETDEVICECHARACTERISTICSANDSECTORSIZE, "OS;0x%X;TVfs::DoGetDeviceCharacteristicsAndSectorSize;driveNo=%d;sectorSize=%d;devCharact=0x%X;readBufSize=%d", (TUint)&aDbFile, driveNo, aDbFile.iSectorSize, (TUint)aDbFile.iDeviceCharacteristics, volumeInfo.iRecReadBufSize)); |
1327 return KErrNone; |
1364 return KErrNone; |
1328 } |
1365 } |
1329 |
1366 |
1330 //Creates a temporary file. The file location will be the application's session path. |
1367 //Creates a temporary file. The file location will be the application's session path. |
1331 //If the session path does not exist, then the function will create the session path. |
1368 //If the session path does not exist, then the function will create the session path. |
1355 } |
1392 } |
1356 } |
1393 } |
1357 } |
1394 } |
1358 return err; |
1395 return err; |
1359 } |
1396 } |
|
1397 |
|
1398 /** |
|
1399 SQLite OS porting layer API. |
|
1400 |
|
1401 The behaviour of the RFile/RFile64::SetSize operation is not atomic for non-rugged drives. |
|
1402 When RFile/RFile64::SetSize() is called 2 operations occurs:- |
|
1403 |
|
1404 1)The cluster chain of the file is updated. |
|
1405 2)The new file size is added to the file cache. |
|
1406 |
|
1407 If a power loss occurs after a SetSize there is a chance that the cluster chain was updated |
|
1408 but the new file size is not yet flushed to the file. This puts the file into an inconsistent state. |
|
1409 This is most likely to occur in the journal file where the time between a SetSize and Flush can |
|
1410 be long. |
|
1411 |
|
1412 For this reason this check is added when the file is opened to see if the end of the file can |
|
1413 be read straight away, if an error is returned then it is assumed that the SetSize has not be |
|
1414 completed previously. In this case the file is deleted and re-created. |
|
1415 |
|
1416 @param aDbFile A pointer to a TDbFile instance, that contains the file handle. |
|
1417 @param aFname A string of 16-bit wide characters containing name of the file to be checked. |
|
1418 @param aFmode The mode in which the file is opened. These mode are documented in TFileMode. |
|
1419 |
|
1420 @return KErrNone, The operation has completed succesfully; |
|
1421 Note that other system-wide error codes may also be returned. |
|
1422 @see TFileMode |
|
1423 @see TVfs::Open() |
|
1424 @see TDbFile |
|
1425 */ |
|
1426 /* static */ TInt TVfs::DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode) |
|
1427 { |
|
1428 const TInt KMinSize = 16; |
|
1429 TInt64 size; |
|
1430 TInt err = KErrNone ; |
|
1431 TBuf8<KMinSize> buf; |
|
1432 |
|
1433 err = aDbFile.iFileBuf.Size(size); |
|
1434 if (err != KErrNone) |
|
1435 { |
|
1436 return err; |
|
1437 } |
|
1438 TBool IsMinFileSize = (size >= KMinSize); |
|
1439 |
|
1440 if (IsMinFileSize) |
|
1441 { |
|
1442 err = aDbFile.iFileBuf.Read(size - KMinSize, buf); |
|
1443 } |
|
1444 |
|
1445 if (err == KErrCorrupt || err == KErrEof || !IsMinFileSize) |
|
1446 { |
|
1447 aDbFile.iFileBuf.Close(); |
|
1448 __SQLITETRACE_OSEXPR(TInt err2 =) TStaticFs::Fs().Delete(aFname); |
|
1449 SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TVFS_DOFILESIZECORRUPTIONCHECK1, "OS;0x%X;TVfs::DoFileSizeCorruptionCheck;size=%lld;err=%d;deleteErr=%d", (TUint)&aDbFile, size, err, err2)); |
|
1450 err = aDbFile.iFileBuf.Create(TStaticFs::Fs(), aFname, aFmode); |
|
1451 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_DOFILESIZECORRUPTIONCHECK2, "OS;0x%X;TVfs::DoFileSizeCorruptionCheck;createErr=%d", (TUint)&aDbFile, err)); |
|
1452 } |
|
1453 return err; |
|
1454 } |
1360 |
1455 |
1361 /** |
1456 /** |
1362 SQLite OS porting layer API. |
1457 SQLite OS porting layer API. |
1363 |
1458 |
1364 Opens or creates a file which name is in the aFileName parameter. |
1459 Opens or creates a file which name is in the aFileName parameter. |
1386 |
1481 |
1387 @see TDbFile |
1482 @see TDbFile |
1388 */ |
1483 */ |
1389 /* static */ int TVfs::Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags) |
1484 /* static */ int TVfs::Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags) |
1390 { |
1485 { |
1391 SQLUTRACE_PROFILER(aVfs); |
|
1392 TFileName fname; |
1486 TFileName fname; |
1393 if(aFileName && !::ConvertToUnicode(aFileName, fname)) |
1487 if(aFileName && !::ConvertToUnicode(aFileName, fname)) |
1394 { |
1488 { |
|
1489 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_OPEN1, "OS;0;TVfs::Open;ConvertToUnicode() failed")); |
1395 return SQLITE_CANTOPEN; |
1490 return SQLITE_CANTOPEN; |
1396 } |
1491 } |
1397 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileOpen, aDbFile, &fname)); |
|
1398 new (aDbFile) TDbFile; |
1492 new (aDbFile) TDbFile; |
1399 TDbFile& dbFile = ::DbFile(aDbFile); |
1493 TDbFile& dbFile = ::DbFile(aDbFile); |
|
1494 SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TVFS_OPEN_ENTRY, "OS-Entry;0x%X;TVfs::Open;fname=%S;aFlags=0x%X", (TUint)&aDbFile, __SQLITEPRNSTR(fname), (TUint)aFlags)); |
1400 if(aFileName && (aFlags & SQLITE_OPEN_DELETEONCLOSE)) |
1495 if(aFileName && (aFlags & SQLITE_OPEN_DELETEONCLOSE)) |
1401 { |
1496 { |
1402 dbFile.iFullName = fname.Alloc(); |
1497 dbFile.iFullName = fname.Alloc(); |
1403 if(!dbFile.iFullName) |
1498 if(!dbFile.iFullName) |
1404 { |
1499 { |
|
1500 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_OPEN2, "OS;0;TVfs::Open;fname.Alloc() failed")); |
1405 return SQLITE_IOERR_NOMEM; |
1501 return SQLITE_IOERR_NOMEM; |
1406 } |
1502 } |
1407 } |
1503 } |
1408 TInt recReadBufSize = -1; |
1504 TInt recReadBufSize = -1; |
1409 TInt err = KErrNone; |
1505 TInt err = KErrNone; |
1425 {//Create temporary file |
1521 {//Create temporary file |
1426 err = ::CreateTempFile(dbFile, fname, fmode); |
1522 err = ::CreateTempFile(dbFile, fname, fmode); |
1427 } |
1523 } |
1428 else |
1524 else |
1429 { |
1525 { |
1430 err = KErrGeneral;//The error has to be set here, because, there is case where none of the file create/open operations will be executed |
1526 err = KErrAccessDenied;//The error has to be set here, because, there is a case where none of the file create/open operations will be executed |
|
1527 TInt prevErr = KErrNone; |
1431 if(aFlags & SQLITE_OPEN_CREATE) |
1528 if(aFlags & SQLITE_OPEN_CREATE) |
1432 { |
1529 { |
1433 err = dbFile.iFileBuf.Create(TStaticFs::Fs(), fname, fmode); |
1530 prevErr = err = dbFile.iFileBuf.Create(TStaticFs::Fs(), fname, fmode); |
1434 } |
1531 } |
1435 if(err != KErrNone && err != KErrNoMemory) |
1532 if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) |
1436 { |
1533 { |
1437 err = dbFile.iFileBuf.Open(TStaticFs::Fs(), fname, fmode); |
1534 err = dbFile.iFileBuf.Open(TStaticFs::Fs(), fname, fmode); |
1438 } |
1535 if(err == KErrNone && (aFlags & KJournalFileTypeBitMask)) |
1439 if((err != KErrNone && err != KErrNoMemory) && (aFlags & SQLITE_OPEN_READWRITE)) |
1536 { |
|
1537 err = TVfs::DoFileSizeCorruptionCheck(dbFile, fname, fmode); |
|
1538 } |
|
1539 } |
|
1540 if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE)) |
1440 { |
1541 { |
1441 aFlags &= ~SQLITE_OPEN_READWRITE; |
1542 aFlags &= ~SQLITE_OPEN_READWRITE; |
1442 aFlags |= SQLITE_OPEN_READONLY; |
1543 aFlags |= SQLITE_OPEN_READONLY; |
1443 fmode &= ~EFileWrite; |
1544 fmode &= ~EFileWrite; |
1444 err = dbFile.iFileBuf.Open(TStaticFs::Fs(), fname, fmode); |
1545 err = dbFile.iFileBuf.Open(TStaticFs::Fs(), fname, fmode); |
1445 } |
1546 } |
|
1547 if(err != KErrNone && prevErr == KErrAccessDenied) |
|
1548 { |
|
1549 err = KErrAccessDenied; |
|
1550 } |
1446 } |
1551 } |
1447 if(err == KErrNone) |
1552 if(err == KErrNone) |
1448 { |
1553 { |
1449 err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(dbFile, recReadBufSize); |
1554 err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(dbFile, recReadBufSize); |
1450 } |
1555 } |
1451 if(err != KErrNone) |
1556 if(err != KErrNone) |
1452 { |
1557 { |
1453 dbFile.iFileBuf.Close(); |
1558 dbFile.iFileBuf.Close(); |
1454 delete dbFile.iFullName; |
1559 delete dbFile.iFullName; |
1455 dbFile.iFullName = NULL; |
1560 dbFile.iFullName = NULL; |
|
1561 if(!aFileName && fname.Length() > 0) |
|
1562 {//temporary file, the error is not KErrNone. Then delete the file (after a successfull |
|
1563 //temporary file creation there could be a failed memory allocation) |
|
1564 (void)TStaticFs::Fs().Delete(fname); |
|
1565 } |
1456 } |
1566 } |
1457 else |
1567 else |
1458 { |
1568 { |
1459 dbFile.pMethods = &TheFileIoApi; |
1569 dbFile.pMethods = &TheFileIoApi; |
1460 dbFile.iReadOnly = !(aFlags & SQLITE_OPEN_READWRITE); |
1570 dbFile.iReadOnly = !(aFlags & SQLITE_OPEN_READWRITE); |
1463 *aOutFlags = dbFile.iReadOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE; |
1573 *aOutFlags = dbFile.iReadOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE; |
1464 } |
1574 } |
1465 (void)dbFile.iFileBuf.SetReadAheadSize(dbFile.iSectorSize, recReadBufSize); |
1575 (void)dbFile.iFileBuf.SetReadAheadSize(dbFile.iSectorSize, recReadBufSize); |
1466 OpenCounter(+1); |
1576 OpenCounter(+1); |
1467 } |
1577 } |
1468 return ::Os2SqliteErr(err, SQLITE_CANTOPEN); |
1578 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_CANTOPEN); |
|
1579 SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TVFS_OPEN_EXIT, "OS-Exit;0x%X;TVfs::Open;outFlags=0x%X;err=%d;sqliteErr=%d", (TUint)&aDbFile, aOutFlags ? (TUint)*aOutFlags : 0, err, sqliteErr)); |
|
1580 return sqliteErr; |
1469 } |
1581 } |
1470 |
1582 |
1471 /** |
1583 /** |
1472 SQLite OS porting layer API. |
1584 SQLite OS porting layer API. |
1473 |
1585 |
1481 SQLITE_IOERR_DELETE,The delete file operation has failed; |
1593 SQLITE_IOERR_DELETE,The delete file operation has failed; |
1482 SQLITE_OK, The operation has completed successfully. |
1594 SQLITE_OK, The operation has completed successfully. |
1483 */ |
1595 */ |
1484 /* static */ int TVfs::Delete(sqlite3_vfs* aVfs, const char* aFileName, int /*aSyncDir*/) |
1596 /* static */ int TVfs::Delete(sqlite3_vfs* aVfs, const char* aFileName, int /*aSyncDir*/) |
1485 { |
1597 { |
1486 SQLUTRACE_PROFILER(aVfs); |
|
1487 SimulateIOError(return SQLITE_IOERR_DELETE); |
1598 SimulateIOError(return SQLITE_IOERR_DELETE); |
1488 TFileName fname; |
1599 TFileName fname; |
1489 if(!::ConvertToUnicode(aFileName, fname)) |
1600 if(!::ConvertToUnicode(aFileName, fname)) |
1490 { |
1601 { |
|
1602 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_DELETE1, "OS;0;TVfs::Delete;ConvertToUnicode() failed")); |
1491 return SQLITE_ERROR; |
1603 return SQLITE_ERROR; |
1492 } |
1604 } |
1493 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileName, &fname)); |
|
1494 TInt err = TStaticFs::Fs().Delete(fname); |
1605 TInt err = TStaticFs::Fs().Delete(fname); |
1495 return ::Os2SqliteErr(err, SQLITE_IOERR_DELETE); |
1606 TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_DELETE); |
|
1607 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_DELETE2, "OS;0;TVfs::Delete;err=%d;sqliteErr=%d", err, sqliteErr)); |
|
1608 return sqliteErr; |
1496 } |
1609 } |
1497 |
1610 |
1498 /** |
1611 /** |
1499 SQLite OS porting layer API. |
1612 SQLite OS porting layer API. |
1500 |
1613 |
1509 SQLITE_IOERR_NOMEM, An out of memory conditon has occured, |
1622 SQLITE_IOERR_NOMEM, An out of memory conditon has occured, |
1510 SQLITE_IOERR_ACCESS,File I/O error; |
1623 SQLITE_IOERR_ACCESS,File I/O error; |
1511 */ |
1624 */ |
1512 /* static */ int TVfs::Access(sqlite3_vfs* aVfs, const char* aFileName, int aFlags, int* aResOut) |
1625 /* static */ int TVfs::Access(sqlite3_vfs* aVfs, const char* aFileName, int aFlags, int* aResOut) |
1513 { |
1626 { |
1514 SQLUTRACE_PROFILER(aVfs); |
|
1515 TFileName fname; |
1627 TFileName fname; |
1516 if(!::ConvertToUnicode(aFileName, fname)) |
1628 if(!::ConvertToUnicode(aFileName, fname)) |
1517 { |
1629 { |
|
1630 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_ACCESS1, "OS;0;TVfs::Access;ConvertToUnicode() failed")); |
1518 return SQLITE_IOERR_ACCESS; |
1631 return SQLITE_IOERR_ACCESS; |
1519 } |
1632 } |
1520 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileName, &fname)); |
1633 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_ACCESS_ENTRY, "OS-Entry;0;TVfs::Access;fname=%S;aFlags=0x%X", __SQLITEPRNSTR(fname), (TUint)aFlags)); |
1521 TEntry entry; |
1634 TEntry entry; |
1522 TInt err = TStaticFs::Fs().Entry(fname, entry); |
1635 TInt err = TStaticFs::Fs().Entry(fname, entry); |
1523 if(aFlags == SQLITE_ACCESS_EXISTS && err == KErrNotFound) |
1636 if(aFlags == SQLITE_ACCESS_EXISTS && err == KErrNotFound) |
1524 { |
1637 { |
1525 *aResOut = 0; |
1638 *aResOut = 0; |
|
1639 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_ACCESS_EXIT1, "OS-Exit;0;TVfs::Access;Exists-NoFound")); |
1526 return SQLITE_OK; |
1640 return SQLITE_OK; |
1527 } |
1641 } |
1528 if(err != KErrNone) |
1642 if(err != KErrNone) |
1529 { |
1643 { |
|
1644 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TVFS_ACCESS_EXIT2, "OS-Exit;0;TVfs::Access;err=%d", err)); |
1530 return err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_IOERR_ACCESS; |
1645 return err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_IOERR_ACCESS; |
1531 } |
1646 } |
1532 *aResOut = 0; |
1647 *aResOut = 0; |
1533 switch(aFlags) |
1648 switch(aFlags) |
1534 { |
1649 { |
1573 @return SQLITE_ERROR, The aRelative parameter is NULL or cannot be converted to UTF16; |
1689 @return SQLITE_ERROR, The aRelative parameter is NULL or cannot be converted to UTF16; |
1574 SQLITE_OK The operation has completed successfully. |
1690 SQLITE_OK The operation has completed successfully. |
1575 */ |
1691 */ |
1576 /* static */ int TVfs::FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf) |
1692 /* static */ int TVfs::FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf) |
1577 { |
1693 { |
1578 SQLUTRACE_PROFILER(aVfs); |
|
1579 if(!aRelative) //NULL argument |
1694 if(!aRelative) //NULL argument |
1580 { |
1695 { |
|
1696 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME1, "OS;0;TVfs::FullPathName;err=SQLITE_ERROR")); |
1581 return SQLITE_ERROR; |
1697 return SQLITE_ERROR; |
1582 } |
1698 } |
1583 //Convert the received file name to UTF16 |
1699 //Convert the received file name to UTF16 |
1584 TBuf<KMaxFileName + 1> fname; |
1700 TBuf<KMaxFileName + 1> fname; |
1585 if(!::ConvertToUnicode(aRelative, fname)) |
1701 if(!::ConvertToUnicode(aRelative, fname)) |
1586 { |
1702 { |
|
1703 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT1, "OS-Exit;0;TVfs::FullPathName;ConvertToUnicode() failed")); |
1587 return SQLITE_ERROR; |
1704 return SQLITE_ERROR; |
1588 } |
1705 } |
1589 SYMBIAN_TRACE_SQLITE_EVENTS_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EInternals), KFileName, &fname)); |
1706 SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_FULLPATHNAME_ENTRY, "OS-Entry;0;TVfs::FullPathName;fname=%S;aBufLen=%d", __SQLITEPRNSTR(fname), aBufLen)); |
1590 //Search if the file name begins with ".\" - current directory |
1707 //Search if the file name begins with ".\" - current directory |
1591 if(fname.Find(KCwd) == 0) |
1708 if(fname.Find(KCwd) == 0) |
1592 { |
1709 { |
1593 fname.Delete(0, KCwd().Length()); |
1710 fname.Delete(0, KCwd().Length()); |
1594 } |
1711 } |
1595 fname.Append(TChar(0));//Zero-terminate the converted file name |
1712 fname.Append(TChar(0));//Zero-terminate the converted file name |
1596 TFileName defaultPath; |
1713 TFileName defaultPath; |
1597 TInt err = TStaticFs::Fs().SessionPath(defaultPath); |
1714 TInt err = TStaticFs::Fs().SessionPath(defaultPath); |
1598 if(err != KErrNone) |
1715 if(err != KErrNone) |
1599 { |
1716 { |
|
1717 SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT4, "OS-Exit;0;TVfs::FullPathName;SessionPath() failed, err=%d", err)); |
1600 return SQLITE_ERROR; |
1718 return SQLITE_ERROR; |
1601 } |
1719 } |
1602 TParse parse; |
1720 TParse parse; |
1603 (void)parse.Set(fname, &defaultPath, 0);//If fname does not have a path, defaultPath will be used |
1721 (void)parse.Set(fname, &defaultPath, 0);//If fname does not have a path, defaultPath will be used |
1604 TPtr8 dest8(reinterpret_cast <TUint8*> (aBuf), aBufLen); |
1722 TPtr8 dest8(reinterpret_cast <TUint8*> (aBuf), aBufLen); |
1605 if(!::ConvertFromUnicode(parse.FullName(), dest8)) |
1723 if(!::ConvertFromUnicode(parse.FullName(), dest8)) |
1606 { |
1724 { |
|
1725 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT2, "OS-Exit;0;TVfs::FullPathName;ConvertFromUnicode() failed")); |
1607 return SQLITE_ERROR; |
1726 return SQLITE_ERROR; |
1608 } |
1727 } |
|
1728 SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT3, "OS-Exit;0;TVfs::FullPathName;err=SQLITE_OK")); |
1609 return SQLITE_OK; |
1729 return SQLITE_OK; |
1610 } |
1730 } |
1611 |
1731 |
1612 /** |
1732 /** |
1613 SQLite OS porting layer API. |
1733 SQLite OS porting layer API. |
1619 |
1739 |
1620 @return The length of the used part of the output buffer. |
1740 @return The length of the used part of the output buffer. |
1621 */ |
1741 */ |
1622 /* static */ int TVfs::Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf) |
1742 /* static */ int TVfs::Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf) |
1623 { |
1743 { |
1624 SQLUTRACE_PROFILER(aVfs); |
|
1625 const TInt KRandIterations = aBufLen / sizeof(int); |
1744 const TInt KRandIterations = aBufLen / sizeof(int); |
1626 for(TInt i=0;i<KRandIterations;++i) |
1745 for(TInt i=0;i<KRandIterations;++i) |
1627 { |
1746 { |
1628 TInt val = Math::Rand(Seed()); |
1747 TInt val = Math::Rand(Seed()); |
1629 Mem::Copy(&aBuf[i * sizeof(int)], &val, sizeof(val)); |
1748 Mem::Copy(&aBuf[i * sizeof(int)], &val, sizeof(val)); |