1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
14 // The last VFS version for which this file has been updated.
15 constexpr int kLastKnowVfsVersion
= 3;
17 // The last io_methods version for which this file has been updated.
18 constexpr int kLastKnownIOMethodsVersion
= 3;
20 using namespace mozilla
;
23 // Base class. Must be first
25 // This points to the underlying sqlite3_file
26 sqlite3_file pReal
[1];
29 int BaseClose(sqlite3_file
* pFile
) {
30 BaseFile
* p
= (BaseFile
*)pFile
;
31 return p
->pReal
->pMethods
->xClose(p
->pReal
);
34 int BaseRead(sqlite3_file
* pFile
, void* zBuf
, int iAmt
, sqlite_int64 iOfst
) {
35 BaseFile
* p
= (BaseFile
*)pFile
;
36 return p
->pReal
->pMethods
->xRead(p
->pReal
, zBuf
, iAmt
, iOfst
);
39 int BaseWrite(sqlite3_file
* pFile
, const void* zBuf
, int iAmt
,
41 BaseFile
* p
= (BaseFile
*)pFile
;
42 return p
->pReal
->pMethods
->xWrite(p
->pReal
, zBuf
, iAmt
, iOfst
);
45 int BaseTruncate(sqlite3_file
* pFile
, sqlite_int64 size
) {
46 BaseFile
* p
= (BaseFile
*)pFile
;
47 return p
->pReal
->pMethods
->xTruncate(p
->pReal
, size
);
50 int BaseSync(sqlite3_file
* pFile
, int flags
) {
51 BaseFile
* p
= (BaseFile
*)pFile
;
52 return p
->pReal
->pMethods
->xSync(p
->pReal
, flags
);
55 int BaseFileSize(sqlite3_file
* pFile
, sqlite_int64
* pSize
) {
56 BaseFile
* p
= (BaseFile
*)pFile
;
57 return p
->pReal
->pMethods
->xFileSize(p
->pReal
, pSize
);
60 int BaseLock(sqlite3_file
* pFile
, int eLock
) {
61 BaseFile
* p
= (BaseFile
*)pFile
;
62 return p
->pReal
->pMethods
->xLock(p
->pReal
, eLock
);
65 int BaseUnlock(sqlite3_file
* pFile
, int eLock
) {
66 BaseFile
* p
= (BaseFile
*)pFile
;
67 return p
->pReal
->pMethods
->xUnlock(p
->pReal
, eLock
);
70 int BaseCheckReservedLock(sqlite3_file
* pFile
, int* pResOut
) {
71 BaseFile
* p
= (BaseFile
*)pFile
;
72 return p
->pReal
->pMethods
->xCheckReservedLock(p
->pReal
, pResOut
);
75 int BaseFileControl(sqlite3_file
* pFile
, int op
, void* pArg
) {
76 #if defined(MOZ_SQLITE_PERSIST_AUXILIARY_FILES)
77 // Persist auxiliary files (-shm and -wal) on disk, because creating and
78 // deleting them may be expensive on slow storage.
79 // Only do this when there is a journal size limit, so the journal is
80 // truncated instead of deleted on shutdown, that feels safer if the user
81 // moves a database file around without its auxiliary files.
83 ::sqlite3_compileoption_used("DEFAULT_JOURNAL_SIZE_LIMIT"),
84 "A journal size limit ensures the journal is truncated on shutdown");
85 if (op
== SQLITE_FCNTL_PERSIST_WAL
) {
86 *static_cast<int*>(pArg
) = 1;
90 BaseFile
* p
= (BaseFile
*)pFile
;
91 return p
->pReal
->pMethods
->xFileControl(p
->pReal
, op
, pArg
);
94 int BaseSectorSize(sqlite3_file
* pFile
) {
95 BaseFile
* p
= (BaseFile
*)pFile
;
96 return p
->pReal
->pMethods
->xSectorSize(p
->pReal
);
99 int BaseDeviceCharacteristics(sqlite3_file
* pFile
) {
100 BaseFile
* p
= (BaseFile
*)pFile
;
101 return p
->pReal
->pMethods
->xDeviceCharacteristics(p
->pReal
);
104 int BaseShmMap(sqlite3_file
* pFile
, int iPg
, int pgsz
, int bExtend
,
105 void volatile** pp
) {
106 BaseFile
* p
= (BaseFile
*)pFile
;
107 return p
->pReal
->pMethods
->xShmMap(p
->pReal
, iPg
, pgsz
, bExtend
, pp
);
110 int BaseShmLock(sqlite3_file
* pFile
, int offset
, int n
, int flags
) {
111 BaseFile
* p
= (BaseFile
*)pFile
;
112 return p
->pReal
->pMethods
->xShmLock(p
->pReal
, offset
, n
, flags
);
115 void BaseShmBarrier(sqlite3_file
* pFile
) {
116 BaseFile
* p
= (BaseFile
*)pFile
;
117 return p
->pReal
->pMethods
->xShmBarrier(p
->pReal
);
120 int BaseShmUnmap(sqlite3_file
* pFile
, int deleteFlag
) {
121 BaseFile
* p
= (BaseFile
*)pFile
;
122 return p
->pReal
->pMethods
->xShmUnmap(p
->pReal
, deleteFlag
);
125 int BaseFetch(sqlite3_file
* pFile
, sqlite3_int64 iOfst
, int iAmt
, void** pp
) {
126 BaseFile
* p
= (BaseFile
*)pFile
;
127 return p
->pReal
->pMethods
->xFetch(p
->pReal
, iOfst
, iAmt
, pp
);
130 int BaseUnfetch(sqlite3_file
* pFile
, sqlite3_int64 iOfst
, void* pPage
) {
131 BaseFile
* p
= (BaseFile
*)pFile
;
132 return p
->pReal
->pMethods
->xUnfetch(p
->pReal
, iOfst
, pPage
);
135 int BaseOpen(sqlite3_vfs
* vfs
, const char* zName
, sqlite3_file
* pFile
,
136 int flags
, int* pOutFlags
) {
137 BaseFile
* p
= (BaseFile
*)pFile
;
138 sqlite3_vfs
* origVfs
= (sqlite3_vfs
*)(vfs
->pAppData
);
139 int rc
= origVfs
->xOpen(origVfs
, zName
, p
->pReal
, flags
, pOutFlags
);
143 if (p
->pReal
->pMethods
) {
144 // If the io_methods version is higher than the last known one, you should
145 // update this VFS adding appropriate IO methods for any methods added in
146 // the version change.
147 MOZ_ASSERT(p
->pReal
->pMethods
->iVersion
== kLastKnownIOMethodsVersion
);
148 static const sqlite3_io_methods IOmethods
= {
149 kLastKnownIOMethodsVersion
, /* iVersion */
150 BaseClose
, /* xClose */
151 BaseRead
, /* xRead */
152 BaseWrite
, /* xWrite */
153 BaseTruncate
, /* xTruncate */
154 BaseSync
, /* xSync */
155 BaseFileSize
, /* xFileSize */
156 BaseLock
, /* xLock */
157 BaseUnlock
, /* xUnlock */
158 BaseCheckReservedLock
, /* xCheckReservedLock */
159 BaseFileControl
, /* xFileControl */
160 BaseSectorSize
, /* xSectorSize */
161 BaseDeviceCharacteristics
, /* xDeviceCharacteristics */
162 BaseShmMap
, /* xShmMap */
163 BaseShmLock
, /* xShmLock */
164 BaseShmBarrier
, /* xShmBarrier */
165 BaseShmUnmap
, /* xShmUnmap */
166 BaseFetch
, /* xFetch */
167 BaseUnfetch
/* xUnfetch */
169 pFile
->pMethods
= &IOmethods
;
177 namespace mozilla::storage::basevfs
{
179 const char* GetVFSName(bool exclusive
) {
180 return exclusive
? "base-vfs-excl" : "base-vfs";
183 UniquePtr
<sqlite3_vfs
> ConstructVFS(bool exclusive
) {
185 # define EXPECTED_VFS "win32"
186 # define EXPECTED_VFS_EXCL "win32"
188 # define EXPECTED_VFS "unix"
189 # define EXPECTED_VFS_EXCL "unix-excl"
192 if (sqlite3_vfs_find(GetVFSName(exclusive
))) {
197 sqlite3_vfs
* origVfs
;
199 // Use the non-exclusive VFS.
200 origVfs
= sqlite3_vfs_find(nullptr);
201 found
= origVfs
&& origVfs
->zName
&& !strcmp(origVfs
->zName
, EXPECTED_VFS
);
203 origVfs
= sqlite3_vfs_find(EXPECTED_VFS_EXCL
);
204 found
= (origVfs
!= nullptr);
210 // If the VFS version is higher than the last known one, you should update
211 // this VFS adding appropriate methods for any methods added in the version
213 MOZ_ASSERT(origVfs
->iVersion
== kLastKnowVfsVersion
);
216 kLastKnowVfsVersion
, /* iVersion */
217 origVfs
->szOsFile
+ static_cast<int>(sizeof(BaseFile
)), /* szOsFile */
218 origVfs
->mxPathname
, /* mxPathname */
220 GetVFSName(exclusive
), /* zName */
221 origVfs
, /* pAppData */
222 BaseOpen
, /* xOpen */
223 origVfs
->xDelete
, /* xDelete */
224 origVfs
->xAccess
, /* xAccess */
225 origVfs
->xFullPathname
, /* xFullPathname */
226 origVfs
->xDlOpen
, /* xDlOpen */
227 origVfs
->xDlError
, /* xDlError */
228 origVfs
->xDlSym
, /* xDlSym */
229 origVfs
->xDlClose
, /* xDlClose */
230 origVfs
->xRandomness
, /* xRandomness */
231 origVfs
->xSleep
, /* xSleep */
232 origVfs
->xCurrentTime
, /* xCurrentTime */
233 origVfs
->xGetLastError
, /* xGetLastError */
234 origVfs
->xCurrentTimeInt64
, /* xCurrentTimeInt64 */
235 origVfs
->xSetSystemCall
, /* xSetSystemCall */
236 origVfs
->xGetSystemCall
, /* xGetSystemCall */
237 origVfs
->xNextSystemCall
/* xNextSystemCall */
240 return MakeUnique
<sqlite3_vfs
>(vfs
);
243 } // namespace mozilla::storage::basevfs