Have "PRAGMA quick_check" compare the number of entries in tables and indexes.
[sqlite.git] / ext / misc / memvfs.c
blob83fc9468e69ae654e93ef839d86164f9992e44a1
1 /*
2 ** 2016-09-07
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
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.
19 ** USAGE:
21 ** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336&max=65536", &db,
22 ** SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI,
23 ** "memvfs");
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
43 #include <string.h>
44 #include <assert.h>
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))
58 /* An open file */
59 struct MemFile {
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);
90 ** Methods for MemVfs
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 = {
107 2, /* iVersion */
108 0, /* szOsFile (set when registered) */
109 1024, /* mxPathname */
110 0, /* pNext */
111 "memvfs", /* zName */
112 0, /* pAppData (set when registered) */
113 memOpen, /* xOpen */
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 = {
129 3, /* iVersion */
130 memClose, /* xClose */
131 memRead, /* xRead */
132 memWrite, /* xWrite */
133 memTruncate, /* xTruncate */
134 memSync, /* xSync */
135 memFileSize, /* xFileSize */
136 memLock, /* xLock */
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
156 ** to free.
158 static int memClose(sqlite3_file *pFile){
159 MemFile *p = (MemFile *)pFile;
160 if( p->bFreeOnClose ) sqlite3_free(p->aData);
161 return SQLITE_OK;
165 ** Read data from an mem-file.
167 static int memRead(
168 sqlite3_file *pFile,
169 void *zBuf,
170 int iAmt,
171 sqlite_int64 iOfst
173 MemFile *p = (MemFile *)pFile;
174 memcpy(zBuf, p->aData+iOfst, iAmt);
175 return SQLITE_OK;
179 ** Write data to an mem-file.
181 static int memWrite(
182 sqlite3_file *pFile,
183 const void *z,
184 int iAmt,
185 sqlite_int64 iOfst
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);
191 p->sz = iOfst+iAmt;
193 memcpy(p->aData+iOfst, z, iAmt);
194 return SQLITE_OK;
198 ** Truncate an mem-file.
200 static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){
201 MemFile *p = (MemFile *)pFile;
202 if( size>p->sz ){
203 if( size>p->szMax ) return SQLITE_FULL;
204 memset(p->aData+p->sz, 0, size-p->sz);
206 p->sz = size;
207 return SQLITE_OK;
211 ** Sync an mem-file.
213 static int memSync(sqlite3_file *pFile, int flags){
214 return SQLITE_OK;
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;
222 *pSize = p->sz;
223 return SQLITE_OK;
227 ** Lock an mem-file.
229 static int memLock(sqlite3_file *pFile, int eLock){
230 return SQLITE_OK;
234 ** Unlock an mem-file.
236 static int memUnlock(sqlite3_file *pFile, int eLock){
237 return SQLITE_OK;
241 ** Check if another file-handle holds a RESERVED lock on an mem-file.
243 static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){
244 *pResOut = 0;
245 return SQLITE_OK;
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);
256 rc = SQLITE_OK;
258 return rc;
262 ** Return the sector-size in bytes for an mem-file.
264 static int memSectorSize(sqlite3_file *pFile){
265 return 1024;
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(
280 sqlite3_file *pFile,
281 int iPg,
282 int pgsz,
283 int bExtend,
284 void volatile **pp
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){
296 return;
299 /* Unmap a shared memory segment */
300 static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){
301 return SQLITE_OK;
304 /* Fetch a page of a memory-mapped file */
305 static int memFetch(
306 sqlite3_file *pFile,
307 sqlite3_int64 iOfst,
308 int iAmt,
309 void **pp
311 MemFile *p = (MemFile *)pFile;
312 *pp = (void*)(p->aData + iOfst);
313 return SQLITE_OK;
316 /* Release a memory-mapped page */
317 static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
318 return SQLITE_OK;
322 ** Open an mem file handle.
324 static int memOpen(
325 sqlite3_vfs *pVfs,
326 const char *zName,
327 sqlite3_file *pFile,
328 int flags,
329 int *pOutFlags
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;
342 return SQLITE_OK;
346 ** Delete the file located at zPath. If the dirSync argument is true,
347 ** ensure the file-system modifications are synced to disk before
348 ** returning.
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(
359 sqlite3_vfs *pVfs,
360 const char *zPath,
361 int flags,
362 int *pResOut
364 *pResOut = 0;
365 return SQLITE_OK;
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(
374 sqlite3_vfs *pVfs,
375 const char *zPath,
376 int nOut,
377 char *zOut
379 sqlite3_snprintf(nOut, zOut, "%s", zPath);
380 return SQLITE_OK;
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
415 ** random data.
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
423 ** actually slept.
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);
443 #ifdef MEMVFS_TEST
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
456 ** file on disk.
458 #include <stdio.h>
459 static void memvfsFromFileFunc(
460 sqlite3_context *context,
461 int argc,
462 sqlite3_value **argv
464 unsigned char *p;
465 sqlite3_int64 sz;
466 sqlite3_int64 szMax;
467 FILE *in;
468 const char *zFilename = (const char*)sqlite3_value_text(argv[0]);
469 char *zUri;
471 if( zFilename==0 ) return;
472 in = fopen(zFilename, "rb");
473 if( in==0 ) return;
474 fseek(in, 0, SEEK_END);
475 szMax = sz = ftell(in);
476 rewind(in);
477 if( argc>=2 ){
478 szMax = sqlite3_value_int64(argv[1]);
479 if( szMax<sz ) szMax = sz;
481 p = sqlite3_malloc64( szMax );
482 if( p==0 ){
483 fclose(in);
484 sqlite3_result_error_nomem(context);
485 return;
487 fread(p, sz, 1, in);
488 fclose(in);
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 */
496 #ifdef 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,
505 int argc,
506 sqlite3_value **argv
508 MemFile *p = 0;
509 FILE *out;
510 int rc;
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");
518 if( out==0 ) return;
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);
523 if( rc ) return;
524 fwrite(p->aData, 1, (size_t)p->sz, out);
525 fclose(out);
527 #endif /* MEMVFS_TEST */
529 #ifdef MEMVFS_TEST
530 /* Called for each new database connection */
531 static int memvfsRegister(
532 sqlite3 *db,
533 char **pzErrMsg,
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);
542 return SQLITE_OK;
544 #endif /* MEMVFS_TEST */
547 #ifdef _WIN32
548 __declspec(dllexport)
549 #endif
551 ** This routine is called when the extension is loaded.
552 ** Register the new VFS.
554 int sqlite3_memvfs_init(
555 sqlite3 *db,
556 char **pzErrMsg,
557 const sqlite3_api_routines *pApi
559 int rc = SQLITE_OK;
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);
565 #ifdef MEMVFS_TEST
566 if( rc==SQLITE_OK ){
567 rc = sqlite3_auto_extension((void(*)(void))memvfsRegister);
569 if( rc==SQLITE_OK ){
570 rc = memvfsRegister(db, pzErrMsg, pApi);
572 #endif
573 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
574 return rc;