4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 ******************************************************************************
13 ** This is an in-memory read-only VFS implementation. The application
14 ** supplies a block of memory which is the database file, and this VFS
15 ** uses that block of memory.
17 ** Because there is no place to store journals and no good way to lock
18 ** the "file", this VFS is read-only.
22 ** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336", &db,
23 ** SQLITE_OPEN_READONLY | SQLITE_OPEN_URI,
26 ** The ptr= and sz= query parameters are required or the open will fail.
27 ** The ptr= parameter gives the memory address of the buffer holding the
28 ** read-only database and sz= gives the size of the database. The parameter
29 ** values may be in hexadecimal or decimal. The filename is ignored.
31 #include <sqlite3ext.h>
32 SQLITE_EXTENSION_INIT1
38 ** Forward declaration of objects used by this utility
40 typedef struct sqlite3_vfs MemVfs
;
41 typedef struct MemFile MemFile
;
43 /* Access to a lower-level VFS that (might) implement dynamic loading,
44 ** access to randomness, etc.
46 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
50 sqlite3_file base
; /* IO methods */
51 sqlite3_int64 sz
; /* Size of the file */
52 unsigned char *aData
; /* content of the file */
56 ** Methods for MemFile
58 static int memClose(sqlite3_file
*);
59 static int memRead(sqlite3_file
*, void*, int iAmt
, sqlite3_int64 iOfst
);
60 static int memWrite(sqlite3_file
*,const void*,int iAmt
, sqlite3_int64 iOfst
);
61 static int memTruncate(sqlite3_file
*, sqlite3_int64 size
);
62 static int memSync(sqlite3_file
*, int flags
);
63 static int memFileSize(sqlite3_file
*, sqlite3_int64
*pSize
);
64 static int memLock(sqlite3_file
*, int);
65 static int memUnlock(sqlite3_file
*, int);
66 static int memCheckReservedLock(sqlite3_file
*, int *pResOut
);
67 static int memFileControl(sqlite3_file
*, int op
, void *pArg
);
68 static int memSectorSize(sqlite3_file
*);
69 static int memDeviceCharacteristics(sqlite3_file
*);
70 static int memShmMap(sqlite3_file
*, int iPg
, int pgsz
, int, void volatile**);
71 static int memShmLock(sqlite3_file
*, int offset
, int n
, int flags
);
72 static void memShmBarrier(sqlite3_file
*);
73 static int memShmUnmap(sqlite3_file
*, int deleteFlag
);
74 static int memFetch(sqlite3_file
*, sqlite3_int64 iOfst
, int iAmt
, void **pp
);
75 static int memUnfetch(sqlite3_file
*, sqlite3_int64 iOfst
, void *p
);
80 static int memOpen(sqlite3_vfs
*, const char *, sqlite3_file
*, int , int *);
81 static int memDelete(sqlite3_vfs
*, const char *zName
, int syncDir
);
82 static int memAccess(sqlite3_vfs
*, const char *zName
, int flags
, int *);
83 static int memFullPathname(sqlite3_vfs
*, const char *zName
, int, char *zOut
);
84 static void *memDlOpen(sqlite3_vfs
*, const char *zFilename
);
85 static void memDlError(sqlite3_vfs
*, int nByte
, char *zErrMsg
);
86 static void (*memDlSym(sqlite3_vfs
*pVfs
, void *p
, const char*zSym
))(void);
87 static void memDlClose(sqlite3_vfs
*, void*);
88 static int memRandomness(sqlite3_vfs
*, int nByte
, char *zOut
);
89 static int memSleep(sqlite3_vfs
*, int microseconds
);
90 static int memCurrentTime(sqlite3_vfs
*, double*);
91 static int memGetLastError(sqlite3_vfs
*, int, char *);
92 static int memCurrentTimeInt64(sqlite3_vfs
*, sqlite3_int64
*);
94 static sqlite3_vfs mem_vfs
= {
96 0, /* szOsFile (set when registered) */
97 1024, /* mxPathname */
100 0, /* pAppData (set when registered) */
102 memDelete
, /* xDelete */
103 memAccess
, /* xAccess */
104 memFullPathname
, /* xFullPathname */
105 memDlOpen
, /* xDlOpen */
106 memDlError
, /* xDlError */
107 memDlSym
, /* xDlSym */
108 memDlClose
, /* xDlClose */
109 memRandomness
, /* xRandomness */
110 memSleep
, /* xSleep */
111 memCurrentTime
, /* xCurrentTime */
112 memGetLastError
, /* xGetLastError */
113 memCurrentTimeInt64
/* xCurrentTimeInt64 */
116 static const sqlite3_io_methods mem_io_methods
= {
118 memClose
, /* xClose */
120 memWrite
, /* xWrite */
121 memTruncate
, /* xTruncate */
123 memFileSize
, /* xFileSize */
125 memUnlock
, /* xUnlock */
126 memCheckReservedLock
, /* xCheckReservedLock */
127 memFileControl
, /* xFileControl */
128 memSectorSize
, /* xSectorSize */
129 memDeviceCharacteristics
, /* xDeviceCharacteristics */
130 memShmMap
, /* xShmMap */
131 memShmLock
, /* xShmLock */
132 memShmBarrier
, /* xShmBarrier */
133 memShmUnmap
, /* xShmUnmap */
134 memFetch
, /* xFetch */
135 memUnfetch
/* xUnfetch */
141 ** Close an mem-file.
143 ** The pData pointer is owned by the application, so there is nothing
146 static int memClose(sqlite3_file
*pFile
){
151 ** Read data from an mem-file.
159 MemFile
*p
= (MemFile
*)pFile
;
160 memcpy(zBuf
, p
->aData
+iOfst
, iAmt
);
165 ** Write data to an mem-file.
173 return SQLITE_READONLY
;
177 ** Truncate an mem-file.
179 static int memTruncate(sqlite3_file
*pFile
, sqlite_int64 size
){
180 return SQLITE_READONLY
;
186 static int memSync(sqlite3_file
*pFile
, int flags
){
187 return SQLITE_READONLY
;
191 ** Return the current file-size of an mem-file.
193 static int memFileSize(sqlite3_file
*pFile
, sqlite_int64
*pSize
){
194 MemFile
*p
= (MemFile
*)pFile
;
202 static int memLock(sqlite3_file
*pFile
, int eLock
){
203 return SQLITE_READONLY
;
207 ** Unlock an mem-file.
209 static int memUnlock(sqlite3_file
*pFile
, int eLock
){
214 ** Check if another file-handle holds a RESERVED lock on an mem-file.
216 static int memCheckReservedLock(sqlite3_file
*pFile
, int *pResOut
){
222 ** File control method. For custom operations on an mem-file.
224 static int memFileControl(sqlite3_file
*pFile
, int op
, void *pArg
){
225 MemFile
*p
= (MemFile
*)pFile
;
226 int rc
= SQLITE_NOTFOUND
;
227 if( op
==SQLITE_FCNTL_VFSNAME
){
228 *(char**)pArg
= sqlite3_mprintf("mem(%p,%lld)", p
->aData
, p
->sz
);
235 ** Return the sector-size in bytes for an mem-file.
237 static int memSectorSize(sqlite3_file
*pFile
){
242 ** Return the device characteristic flags supported by an mem-file.
244 static int memDeviceCharacteristics(sqlite3_file
*pFile
){
245 return SQLITE_IOCAP_IMMUTABLE
;
248 /* Create a shared memory file mapping */
249 static int memShmMap(
256 return SQLITE_READONLY
;
259 /* Perform locking on a shared-memory segment */
260 static int memShmLock(sqlite3_file
*pFile
, int offset
, int n
, int flags
){
261 return SQLITE_READONLY
;
264 /* Memory barrier operation on shared memory */
265 static void memShmBarrier(sqlite3_file
*pFile
){
269 /* Unmap a shared memory segment */
270 static int memShmUnmap(sqlite3_file
*pFile
, int deleteFlag
){
274 /* Fetch a page of a memory-mapped file */
281 MemFile
*p
= (MemFile
*)pFile
;
282 *pp
= (void*)(p
->aData
+ iOfst
);
286 /* Release a memory-mapped page */
287 static int memUnfetch(sqlite3_file
*pFile
, sqlite3_int64 iOfst
, void *pPage
){
292 ** Open an mem file handle.
301 MemFile
*p
= (MemFile
*)pFile
;
302 memset(p
, 0, sizeof(*p
));
303 if( (flags
& SQLITE_OPEN_MAIN_DB
)==0 ) return SQLITE_CANTOPEN
;
304 p
->aData
= (unsigned char*)sqlite3_uri_int64(zName
,"ptr",0);
305 if( p
->aData
==0 ) return SQLITE_CANTOPEN
;
306 p
->sz
= sqlite3_uri_int64(zName
,"sz",0);
307 if( p
->sz
<0 ) return SQLITE_CANTOPEN
;
308 pFile
->pMethods
= &mem_io_methods
;
313 ** Delete the file located at zPath. If the dirSync argument is true,
314 ** ensure the file-system modifications are synced to disk before
317 static int memDelete(sqlite3_vfs
*pVfs
, const char *zPath
, int dirSync
){
318 return SQLITE_READONLY
;
322 ** Test for access permissions. Return true if the requested permission
323 ** is available, or false otherwise.
325 static int memAccess(
331 /* The spec says there are three possible values for flags. But only
332 ** two of them are actually used */
333 assert( flags
==SQLITE_ACCESS_EXISTS
|| flags
==SQLITE_ACCESS_READWRITE
);
334 if( flags
==SQLITE_ACCESS_READWRITE
){
343 ** Populate buffer zOut with the full canonical pathname corresponding
344 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
345 ** of at least (INST_MAX_PATHNAME+1) bytes.
347 static int memFullPathname(
353 sqlite3_snprintf(nOut
, zOut
, "%s", zPath
);
358 ** Open the dynamic library located at zPath and return a handle.
360 static void *memDlOpen(sqlite3_vfs
*pVfs
, const char *zPath
){
361 return ORIGVFS(pVfs
)->xDlOpen(ORIGVFS(pVfs
), zPath
);
365 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
366 ** utf-8 string describing the most recent error encountered associated
367 ** with dynamic libraries.
369 static void memDlError(sqlite3_vfs
*pVfs
, int nByte
, char *zErrMsg
){
370 ORIGVFS(pVfs
)->xDlError(ORIGVFS(pVfs
), nByte
, zErrMsg
);
374 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
376 static void (*memDlSym(sqlite3_vfs
*pVfs
, void *p
, const char *zSym
))(void){
377 return ORIGVFS(pVfs
)->xDlSym(ORIGVFS(pVfs
), p
, zSym
);
381 ** Close the dynamic library handle pHandle.
383 static void memDlClose(sqlite3_vfs
*pVfs
, void *pHandle
){
384 ORIGVFS(pVfs
)->xDlClose(ORIGVFS(pVfs
), pHandle
);
388 ** Populate the buffer pointed to by zBufOut with nByte bytes of
391 static int memRandomness(sqlite3_vfs
*pVfs
, int nByte
, char *zBufOut
){
392 return ORIGVFS(pVfs
)->xRandomness(ORIGVFS(pVfs
), nByte
, zBufOut
);
396 ** Sleep for nMicro microseconds. Return the number of microseconds
399 static int memSleep(sqlite3_vfs
*pVfs
, int nMicro
){
400 return ORIGVFS(pVfs
)->xSleep(ORIGVFS(pVfs
), nMicro
);
404 ** Return the current time as a Julian Day number in *pTimeOut.
406 static int memCurrentTime(sqlite3_vfs
*pVfs
, double *pTimeOut
){
407 return ORIGVFS(pVfs
)->xCurrentTime(ORIGVFS(pVfs
), pTimeOut
);
410 static int memGetLastError(sqlite3_vfs
*pVfs
, int a
, char *b
){
411 return ORIGVFS(pVfs
)->xGetLastError(ORIGVFS(pVfs
), a
, b
);
413 static int memCurrentTimeInt64(sqlite3_vfs
*pVfs
, sqlite3_int64
*p
){
414 return ORIGVFS(pVfs
)->xCurrentTimeInt64(ORIGVFS(pVfs
), p
);
421 ** This an SQL function used to help in testing the memvfs VFS. The
422 ** function reads the content of a file into memory and then returns
423 ** a string that gives the locate and size of the in-memory buffer.
426 static void memvfsMemloadFunc(
427 sqlite3_context
*context
,
434 const char *zFilename
= (const char*)sqlite3_value_text(argv
[0]);
437 if( zFilename
==0 ) return;
438 in
= fopen(zFilename
, "rb");
440 fseek(in
, 0, SEEK_END
);
443 p
= sqlite3_malloc( sz
);
446 sqlite3_result_error_nomem(context
);
451 sqlite3_snprintf(sizeof(zReturn
),zReturn
,"ptr=%lld&sz=%lld",
452 (sqlite3_int64
)p
, sz
);
453 sqlite3_result_text(context
, zReturn
, -1, SQLITE_TRANSIENT
);
455 /* Called for each new database connection */
456 static int memvfsRegister(
458 const char **pzErrMsg
,
459 const struct sqlite3_api_routines
*pThunk
461 return sqlite3_create_function(db
, "memload", 1, SQLITE_UTF8
, 0,
462 memvfsMemloadFunc
, 0, 0);
464 #endif /* MEMVFS_TEST */
468 __declspec(dllexport
)
471 ** This routine is called when the extension is loaded.
472 ** Register the new VFS.
474 int sqlite3_memvfs_init(
477 const sqlite3_api_routines
*pApi
480 SQLITE_EXTENSION_INIT2(pApi
);
481 mem_vfs
.pAppData
= sqlite3_vfs_find(0);
482 mem_vfs
.szOsFile
= sizeof(MemFile
);
483 rc
= sqlite3_vfs_register(&mem_vfs
, 1);
486 rc
= sqlite3_auto_extension((void(*)(void))memvfsRegister
);
489 if( rc
==SQLITE_OK
) rc
= SQLITE_OK_LOAD_PERMANENTLY
;