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 VFS implementation. The application supplies
14 ** a chunk of memory to hold the database file.
16 ** Because there is place to store a rollback or wal journal, the database
17 ** must use one of journal_mode=MEMORY or journal_mode=NONE.
21 ** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336&max=65536", &db,
22 ** SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI,
25 ** These are the query parameters:
27 ** ptr= The address of the memory buffer that holds the database.
29 ** sz= The current size the database file
31 ** maxsz= The maximum size of the database. In other words, the
32 ** amount of space allocated for the ptr= buffer.
34 ** freeonclose= If true, then sqlite3_free() is called on the ptr=
35 ** value when the connection closes.
37 ** The ptr= and sz= query parameters are required. If maxsz= is omitted,
38 ** then it defaults to the sz= value. Parameter values can be in either
39 ** decimal or hexadecimal. The filename in the URI is ignored.
41 #include <sqlite3ext.h>
42 SQLITE_EXTENSION_INIT1
48 ** Forward declaration of objects used by this utility
50 typedef struct sqlite3_vfs MemVfs
;
51 typedef struct MemFile MemFile
;
53 /* Access to a lower-level VFS that (might) implement dynamic loading,
54 ** access to randomness, etc.
56 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
60 sqlite3_file base
; /* IO methods */
61 sqlite3_int64 sz
; /* Size of the file */
62 sqlite3_int64 szMax
; /* Space allocated to aData */
63 unsigned char *aData
; /* content of the file */
64 int bFreeOnClose
; /* Invoke sqlite3_free() on aData at close */
68 ** Methods for MemFile
70 static int memClose(sqlite3_file
*);
71 static int memRead(sqlite3_file
*, void*, int iAmt
, sqlite3_int64 iOfst
);
72 static int memWrite(sqlite3_file
*,const void*,int iAmt
, sqlite3_int64 iOfst
);
73 static int memTruncate(sqlite3_file
*, sqlite3_int64 size
);
74 static int memSync(sqlite3_file
*, int flags
);
75 static int memFileSize(sqlite3_file
*, sqlite3_int64
*pSize
);
76 static int memLock(sqlite3_file
*, int);
77 static int memUnlock(sqlite3_file
*, int);
78 static int memCheckReservedLock(sqlite3_file
*, int *pResOut
);
79 static int memFileControl(sqlite3_file
*, int op
, void *pArg
);
80 static int memSectorSize(sqlite3_file
*);
81 static int memDeviceCharacteristics(sqlite3_file
*);
82 static int memShmMap(sqlite3_file
*, int iPg
, int pgsz
, int, void volatile**);
83 static int memShmLock(sqlite3_file
*, int offset
, int n
, int flags
);
84 static void memShmBarrier(sqlite3_file
*);
85 static int memShmUnmap(sqlite3_file
*, int deleteFlag
);
86 static int memFetch(sqlite3_file
*, sqlite3_int64 iOfst
, int iAmt
, void **pp
);
87 static int memUnfetch(sqlite3_file
*, sqlite3_int64 iOfst
, void *p
);
92 static int memOpen(sqlite3_vfs
*, const char *, sqlite3_file
*, int , int *);
93 static int memDelete(sqlite3_vfs
*, const char *zName
, int syncDir
);
94 static int memAccess(sqlite3_vfs
*, const char *zName
, int flags
, int *);
95 static int memFullPathname(sqlite3_vfs
*, const char *zName
, int, char *zOut
);
96 static void *memDlOpen(sqlite3_vfs
*, const char *zFilename
);
97 static void memDlError(sqlite3_vfs
*, int nByte
, char *zErrMsg
);
98 static void (*memDlSym(sqlite3_vfs
*pVfs
, void *p
, const char*zSym
))(void);
99 static void memDlClose(sqlite3_vfs
*, void*);
100 static int memRandomness(sqlite3_vfs
*, int nByte
, char *zOut
);
101 static int memSleep(sqlite3_vfs
*, int microseconds
);
102 static int memCurrentTime(sqlite3_vfs
*, double*);
103 static int memGetLastError(sqlite3_vfs
*, int, char *);
104 static int memCurrentTimeInt64(sqlite3_vfs
*, sqlite3_int64
*);
106 static sqlite3_vfs mem_vfs
= {
108 0, /* szOsFile (set when registered) */
109 1024, /* mxPathname */
111 "memvfs", /* zName */
112 0, /* pAppData (set when registered) */
114 memDelete
, /* xDelete */
115 memAccess
, /* xAccess */
116 memFullPathname
, /* xFullPathname */
117 memDlOpen
, /* xDlOpen */
118 memDlError
, /* xDlError */
119 memDlSym
, /* xDlSym */
120 memDlClose
, /* xDlClose */
121 memRandomness
, /* xRandomness */
122 memSleep
, /* xSleep */
123 memCurrentTime
, /* xCurrentTime */
124 memGetLastError
, /* xGetLastError */
125 memCurrentTimeInt64
/* xCurrentTimeInt64 */
128 static const sqlite3_io_methods mem_io_methods
= {
130 memClose
, /* xClose */
132 memWrite
, /* xWrite */
133 memTruncate
, /* xTruncate */
135 memFileSize
, /* xFileSize */
137 memUnlock
, /* xUnlock */
138 memCheckReservedLock
, /* xCheckReservedLock */
139 memFileControl
, /* xFileControl */
140 memSectorSize
, /* xSectorSize */
141 memDeviceCharacteristics
, /* xDeviceCharacteristics */
142 memShmMap
, /* xShmMap */
143 memShmLock
, /* xShmLock */
144 memShmBarrier
, /* xShmBarrier */
145 memShmUnmap
, /* xShmUnmap */
146 memFetch
, /* xFetch */
147 memUnfetch
/* xUnfetch */
153 ** Close an mem-file.
155 ** The pData pointer is owned by the application, so there is nothing
158 static int memClose(sqlite3_file
*pFile
){
159 MemFile
*p
= (MemFile
*)pFile
;
160 if( p
->bFreeOnClose
) sqlite3_free(p
->aData
);
165 ** Read data from an mem-file.
173 MemFile
*p
= (MemFile
*)pFile
;
174 memcpy(zBuf
, p
->aData
+iOfst
, iAmt
);
179 ** Write data to an mem-file.
187 MemFile
*p
= (MemFile
*)pFile
;
188 if( iOfst
+iAmt
>p
->sz
){
189 if( iOfst
+iAmt
>p
->szMax
) return SQLITE_FULL
;
190 if( iOfst
>p
->sz
) memset(p
->aData
+p
->sz
, 0, iOfst
-p
->sz
);
193 memcpy(p
->aData
+iOfst
, z
, iAmt
);
198 ** Truncate an mem-file.
200 static int memTruncate(sqlite3_file
*pFile
, sqlite_int64 size
){
201 MemFile
*p
= (MemFile
*)pFile
;
203 if( size
>p
->szMax
) return SQLITE_FULL
;
204 memset(p
->aData
+p
->sz
, 0, size
-p
->sz
);
213 static int memSync(sqlite3_file
*pFile
, int flags
){
218 ** Return the current file-size of an mem-file.
220 static int memFileSize(sqlite3_file
*pFile
, sqlite_int64
*pSize
){
221 MemFile
*p
= (MemFile
*)pFile
;
229 static int memLock(sqlite3_file
*pFile
, int eLock
){
234 ** Unlock an mem-file.
236 static int memUnlock(sqlite3_file
*pFile
, int eLock
){
241 ** Check if another file-handle holds a RESERVED lock on an mem-file.
243 static int memCheckReservedLock(sqlite3_file
*pFile
, int *pResOut
){
249 ** File control method. For custom operations on an mem-file.
251 static int memFileControl(sqlite3_file
*pFile
, int op
, void *pArg
){
252 MemFile
*p
= (MemFile
*)pFile
;
253 int rc
= SQLITE_NOTFOUND
;
254 if( op
==SQLITE_FCNTL_VFSNAME
){
255 *(char**)pArg
= sqlite3_mprintf("mem(%p,%lld)", p
->aData
, p
->sz
);
262 ** Return the sector-size in bytes for an mem-file.
264 static int memSectorSize(sqlite3_file
*pFile
){
269 ** Return the device characteristic flags supported by an mem-file.
271 static int memDeviceCharacteristics(sqlite3_file
*pFile
){
272 return SQLITE_IOCAP_ATOMIC
|
273 SQLITE_IOCAP_POWERSAFE_OVERWRITE
|
274 SQLITE_IOCAP_SAFE_APPEND
|
275 SQLITE_IOCAP_SEQUENTIAL
;
278 /* Create a shared memory file mapping */
279 static int memShmMap(
286 return SQLITE_IOERR_SHMMAP
;
289 /* Perform locking on a shared-memory segment */
290 static int memShmLock(sqlite3_file
*pFile
, int offset
, int n
, int flags
){
291 return SQLITE_IOERR_SHMLOCK
;
294 /* Memory barrier operation on shared memory */
295 static void memShmBarrier(sqlite3_file
*pFile
){
299 /* Unmap a shared memory segment */
300 static int memShmUnmap(sqlite3_file
*pFile
, int deleteFlag
){
304 /* Fetch a page of a memory-mapped file */
311 MemFile
*p
= (MemFile
*)pFile
;
312 *pp
= (void*)(p
->aData
+ iOfst
);
316 /* Release a memory-mapped page */
317 static int memUnfetch(sqlite3_file
*pFile
, sqlite3_int64 iOfst
, void *pPage
){
322 ** Open an mem file handle.
331 MemFile
*p
= (MemFile
*)pFile
;
332 memset(p
, 0, sizeof(*p
));
333 if( (flags
& SQLITE_OPEN_MAIN_DB
)==0 ) return SQLITE_CANTOPEN
;
334 p
->aData
= (unsigned char*)sqlite3_uri_int64(zName
,"ptr",0);
335 if( p
->aData
==0 ) return SQLITE_CANTOPEN
;
336 p
->sz
= sqlite3_uri_int64(zName
,"sz",0);
337 if( p
->sz
<0 ) return SQLITE_CANTOPEN
;
338 p
->szMax
= sqlite3_uri_int64(zName
,"max",p
->sz
);
339 if( p
->szMax
<p
->sz
) return SQLITE_CANTOPEN
;
340 p
->bFreeOnClose
= sqlite3_uri_boolean(zName
,"freeonclose",0);
341 pFile
->pMethods
= &mem_io_methods
;
346 ** Delete the file located at zPath. If the dirSync argument is true,
347 ** ensure the file-system modifications are synced to disk before
350 static int memDelete(sqlite3_vfs
*pVfs
, const char *zPath
, int dirSync
){
351 return SQLITE_IOERR_DELETE
;
355 ** Test for access permissions. Return true if the requested permission
356 ** is available, or false otherwise.
358 static int memAccess(
369 ** Populate buffer zOut with the full canonical pathname corresponding
370 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
371 ** of at least (INST_MAX_PATHNAME+1) bytes.
373 static int memFullPathname(
379 sqlite3_snprintf(nOut
, zOut
, "%s", zPath
);
384 ** Open the dynamic library located at zPath and return a handle.
386 static void *memDlOpen(sqlite3_vfs
*pVfs
, const char *zPath
){
387 return ORIGVFS(pVfs
)->xDlOpen(ORIGVFS(pVfs
), zPath
);
391 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
392 ** utf-8 string describing the most recent error encountered associated
393 ** with dynamic libraries.
395 static void memDlError(sqlite3_vfs
*pVfs
, int nByte
, char *zErrMsg
){
396 ORIGVFS(pVfs
)->xDlError(ORIGVFS(pVfs
), nByte
, zErrMsg
);
400 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
402 static void (*memDlSym(sqlite3_vfs
*pVfs
, void *p
, const char *zSym
))(void){
403 return ORIGVFS(pVfs
)->xDlSym(ORIGVFS(pVfs
), p
, zSym
);
407 ** Close the dynamic library handle pHandle.
409 static void memDlClose(sqlite3_vfs
*pVfs
, void *pHandle
){
410 ORIGVFS(pVfs
)->xDlClose(ORIGVFS(pVfs
), pHandle
);
414 ** Populate the buffer pointed to by zBufOut with nByte bytes of
417 static int memRandomness(sqlite3_vfs
*pVfs
, int nByte
, char *zBufOut
){
418 return ORIGVFS(pVfs
)->xRandomness(ORIGVFS(pVfs
), nByte
, zBufOut
);
422 ** Sleep for nMicro microseconds. Return the number of microseconds
425 static int memSleep(sqlite3_vfs
*pVfs
, int nMicro
){
426 return ORIGVFS(pVfs
)->xSleep(ORIGVFS(pVfs
), nMicro
);
430 ** Return the current time as a Julian Day number in *pTimeOut.
432 static int memCurrentTime(sqlite3_vfs
*pVfs
, double *pTimeOut
){
433 return ORIGVFS(pVfs
)->xCurrentTime(ORIGVFS(pVfs
), pTimeOut
);
436 static int memGetLastError(sqlite3_vfs
*pVfs
, int a
, char *b
){
437 return ORIGVFS(pVfs
)->xGetLastError(ORIGVFS(pVfs
), a
, b
);
439 static int memCurrentTimeInt64(sqlite3_vfs
*pVfs
, sqlite3_int64
*p
){
440 return ORIGVFS(pVfs
)->xCurrentTimeInt64(ORIGVFS(pVfs
), p
);
445 ** memvfs_from_file(FILENAME, MAXSIZE)
447 ** This an SQL function used to help in testing the memvfs VFS. The
448 ** function reads the content of a file into memory and then returns
449 ** a URI that can be handed to ATTACH to attach the memory buffer as
450 ** a database. Example:
452 ** ATTACH memvfs_from_file('test.db',1048576) AS inmem;
454 ** The optional MAXSIZE argument gives the size of the memory allocation
455 ** used to hold the database. If omitted, it defaults to the size of the
459 static void memvfsFromFileFunc(
460 sqlite3_context
*context
,
468 const char *zFilename
= (const char*)sqlite3_value_text(argv
[0]);
471 if( zFilename
==0 ) return;
472 in
= fopen(zFilename
, "rb");
474 fseek(in
, 0, SEEK_END
);
475 szMax
= sz
= ftell(in
);
478 szMax
= sqlite3_value_int64(argv
[1]);
479 if( szMax
<sz
) szMax
= sz
;
481 p
= sqlite3_malloc64( szMax
);
484 sqlite3_result_error_nomem(context
);
489 zUri
= sqlite3_mprintf(
490 "file:/mem?vfs=memvfs&ptr=%lld&sz=%lld&max=%lld&freeonclose=1",
491 (sqlite3_int64
)p
, sz
, szMax
);
492 sqlite3_result_text(context
, zUri
, -1, sqlite3_free
);
494 #endif /* MEMVFS_TEST */
498 ** memvfs_to_file(SCHEMA, FILENAME)
500 ** The schema identified by SCHEMA must be a memvfs database. Write
501 ** the content of this database into FILENAME.
503 static void memvfsToFileFunc(
504 sqlite3_context
*context
,
511 sqlite3
*db
= sqlite3_context_db_handle(context
);
512 sqlite3_vfs
*pVfs
= 0;
513 const char *zSchema
= (const char*)sqlite3_value_text(argv
[0]);
514 const char *zFilename
= (const char*)sqlite3_value_text(argv
[1]);
516 if( zFilename
==0 ) return;
517 out
= fopen(zFilename
, "wb");
519 rc
= sqlite3_file_control(db
, zSchema
, SQLITE_FCNTL_VFS_POINTER
, &pVfs
);
520 if( rc
|| pVfs
==0 ) return;
521 if( strcmp(pVfs
->zName
,"memvfs")!=0 ) return;
522 rc
= sqlite3_file_control(db
, zSchema
, SQLITE_FCNTL_FILE_POINTER
, &p
);
524 fwrite(p
->aData
, 1, (size_t)p
->sz
, out
);
527 #endif /* MEMVFS_TEST */
530 /* Called for each new database connection */
531 static int memvfsRegister(
534 const struct sqlite3_api_routines
*pThunk
536 sqlite3_create_function(db
, "memvfs_from_file", 1, SQLITE_UTF8
, 0,
537 memvfsFromFileFunc
, 0, 0);
538 sqlite3_create_function(db
, "memvfs_from_file", 2, SQLITE_UTF8
, 0,
539 memvfsFromFileFunc
, 0, 0);
540 sqlite3_create_function(db
, "memvfs_to_file", 2, SQLITE_UTF8
, 0,
541 memvfsToFileFunc
, 0, 0);
544 #endif /* MEMVFS_TEST */
548 __declspec(dllexport
)
551 ** This routine is called when the extension is loaded.
552 ** Register the new VFS.
554 int sqlite3_memvfs_init(
557 const sqlite3_api_routines
*pApi
560 SQLITE_EXTENSION_INIT2(pApi
);
561 mem_vfs
.pAppData
= sqlite3_vfs_find(0);
562 if( mem_vfs
.pAppData
==0 ) return SQLITE_ERROR
;
563 mem_vfs
.szOsFile
= sizeof(MemFile
);
564 rc
= sqlite3_vfs_register(&mem_vfs
, 1);
567 rc
= sqlite3_auto_extension((void(*)(void))memvfsRegister
);
570 rc
= memvfsRegister(db
, pzErrMsg
, pApi
);
573 if( rc
==SQLITE_OK
) rc
= SQLITE_OK_LOAD_PERMANENTLY
;