xref: /sqlite-3.40.0/src/memdb.c (revision 1a39e456)
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.
10 **
11 ******************************************************************************
12 **
13 ** This file implements an in-memory VFS. A database is held as a contiguous
14 ** block of memory.
15 **
16 ** This file also implements interface sqlite3_serialize() and
17 ** sqlite3_deserialize().
18 */
19 #include "sqliteInt.h"
20 #ifndef SQLITE_OMIT_DESERIALIZE
21 
22 /*
23 ** Forward declaration of objects used by this utility
24 */
25 typedef struct sqlite3_vfs MemVfs;
26 typedef struct MemFile MemFile;
27 typedef struct MemStore MemStore;
28 
29 /* Access to a lower-level VFS that (might) implement dynamic loading,
30 ** access to randomness, etc.
31 */
32 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
33 
34 /* Storage for a memdb file.
35 **
36 ** An memdb object can be shared or separate.  Shared memdb objects can be
37 ** used by more than one database connection.  Mutexes are used by shared
38 ** memdb objects to coordinate access.  Separate memdb objects are only
39 ** connected to a single database connection and do not require additional
40 ** mutexes.
41 **
42 ** Shared memdb objects have .zFName!=0 and .pMutex!=0.  They are created
43 ** using "file:/name?vfs=memdb".  The first character of the name must be
44 ** "/" or else the object will be a separate memdb object.  All shared
45 ** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order.
46 **
47 ** Separate memdb objects are created using a name that does not begin
48 ** with "/" or using sqlite3_deserialize().
49 **
50 ** Access rules for shared MemStore objects:
51 **
52 **   *  .zFName is initialized when the object is created and afterwards
53 **      is unchanged until the object is destroyed.  So it can be accessed
54 **      at any time as long as we know the object is not being destroyed,
55 **      which means while either the SQLITE_MUTEX_STATIC_VFS1 or
56 **      .pMutex is held or the object is not part of memdb_g.apMemStore[].
57 **
58 **   *  Can .pMutex can only be changed while holding the
59 **      SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part
60 **      of memdb_g.apMemStore[].
61 **
62 **   *  Other fields can only be changed while holding the .pMutex mutex
63 **      or when the .nRef is less than zero and the object is not part of
64 **      memdb_g.apMemStore[].
65 **
66 **   *  The .aData pointer has the added requirement that it can can only
67 **      be changed (for resizing) when nMmap is zero.
68 **
69 */
70 struct MemStore {
71   sqlite3_int64 sz;               /* Size of the file */
72   sqlite3_int64 szAlloc;          /* Space allocated to aData */
73   sqlite3_int64 szMax;            /* Maximum allowed size of the file */
74   unsigned char *aData;           /* content of the file */
75   sqlite3_mutex *pMutex;          /* Used by shared stores only */
76   int nMmap;                      /* Number of memory mapped pages */
77   unsigned mFlags;                /* Flags */
78   int nRdLock;                    /* Number of readers */
79   int nWrLock;                    /* Number of writers.  (Always 0 or 1) */
80   int nRef;                       /* Number of users of this MemStore */
81   char *zFName;                   /* The filename for shared stores */
82 };
83 
84 /* An open file */
85 struct MemFile {
86   sqlite3_file base;              /* IO methods */
87   MemStore *pStore;               /* The storage */
88   int eLock;                      /* Most recent lock against this file */
89 };
90 
91 /*
92 ** File-scope variables for holding the memdb files that are accessible
93 ** to multiple database connections in separate threads.
94 **
95 ** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object.
96 */
97 static struct MemFS {
98   int nMemStore;                  /* Number of shared MemStore objects */
99   MemStore **apMemStore;          /* Array of all shared MemStore objects */
100 } memdb_g;
101 
102 /*
103 ** Methods for MemFile
104 */
105 static int memdbClose(sqlite3_file*);
106 static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
107 static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
108 static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
109 static int memdbSync(sqlite3_file*, int flags);
110 static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
111 static int memdbLock(sqlite3_file*, int);
112 /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
113 static int memdbFileControl(sqlite3_file*, int op, void *pArg);
114 /* static int memdbSectorSize(sqlite3_file*); // not used */
115 static int memdbDeviceCharacteristics(sqlite3_file*);
116 static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
117 static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
118 
119 /*
120 ** Methods for MemVfs
121 */
122 static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
123 /* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
124 static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
125 static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
126 static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
127 static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
128 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
129 static void memdbDlClose(sqlite3_vfs*, void*);
130 static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
131 static int memdbSleep(sqlite3_vfs*, int microseconds);
132 /* static int memdbCurrentTime(sqlite3_vfs*, double*); */
133 static int memdbGetLastError(sqlite3_vfs*, int, char *);
134 static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
135 
136 static sqlite3_vfs memdb_vfs = {
137   2,                           /* iVersion */
138   0,                           /* szOsFile (set when registered) */
139   1024,                        /* mxPathname */
140   0,                           /* pNext */
141   "memdb",                     /* zName */
142   0,                           /* pAppData (set when registered) */
143   memdbOpen,                   /* xOpen */
144   0, /* memdbDelete, */        /* xDelete */
145   memdbAccess,                 /* xAccess */
146   memdbFullPathname,           /* xFullPathname */
147   memdbDlOpen,                 /* xDlOpen */
148   memdbDlError,                /* xDlError */
149   memdbDlSym,                  /* xDlSym */
150   memdbDlClose,                /* xDlClose */
151   memdbRandomness,             /* xRandomness */
152   memdbSleep,                  /* xSleep */
153   0, /* memdbCurrentTime, */   /* xCurrentTime */
154   memdbGetLastError,           /* xGetLastError */
155   memdbCurrentTimeInt64,       /* xCurrentTimeInt64 */
156   0,                           /* xSetSystemCall */
157   0,                           /* xGetSystemCall */
158   0,                           /* xNextSystemCall */
159 };
160 
161 static const sqlite3_io_methods memdb_io_methods = {
162   3,                              /* iVersion */
163   memdbClose,                      /* xClose */
164   memdbRead,                       /* xRead */
165   memdbWrite,                      /* xWrite */
166   memdbTruncate,                   /* xTruncate */
167   memdbSync,                       /* xSync */
168   memdbFileSize,                   /* xFileSize */
169   memdbLock,                       /* xLock */
170   memdbLock,                       /* xUnlock - same as xLock in this case */
171   0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
172   memdbFileControl,                /* xFileControl */
173   0, /* memdbSectorSize,*/         /* xSectorSize */
174   memdbDeviceCharacteristics,      /* xDeviceCharacteristics */
175   0,                               /* xShmMap */
176   0,                               /* xShmLock */
177   0,                               /* xShmBarrier */
178   0,                               /* xShmUnmap */
179   memdbFetch,                      /* xFetch */
180   memdbUnfetch                     /* xUnfetch */
181 };
182 
183 /*
184 ** Enter/leave the mutex on a MemStore
185 */
186 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
memdbEnter(MemStore * p)187 static void memdbEnter(MemStore *p){
188   UNUSED_PARAMETER(p);
189 }
memdbLeave(MemStore * p)190 static void memdbLeave(MemStore *p){
191   UNUSED_PARAMETER(p);
192 }
193 #else
memdbEnter(MemStore * p)194 static void memdbEnter(MemStore *p){
195   sqlite3_mutex_enter(p->pMutex);
196 }
memdbLeave(MemStore * p)197 static void memdbLeave(MemStore *p){
198   sqlite3_mutex_leave(p->pMutex);
199 }
200 #endif
201 
202 
203 
204 /*
205 ** Close an memdb-file.
206 ** Free the underlying MemStore object when its refcount drops to zero
207 ** or less.
208 */
memdbClose(sqlite3_file * pFile)209 static int memdbClose(sqlite3_file *pFile){
210   MemStore *p = ((MemFile*)pFile)->pStore;
211   if( p->zFName ){
212     int i;
213 #ifndef SQLITE_MUTEX_OMIT
214     sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
215 #endif
216     sqlite3_mutex_enter(pVfsMutex);
217     for(i=0; ALWAYS(i<memdb_g.nMemStore); i++){
218       if( memdb_g.apMemStore[i]==p ){
219         memdbEnter(p);
220         if( p->nRef==1 ){
221           memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore];
222           if( memdb_g.nMemStore==0 ){
223             sqlite3_free(memdb_g.apMemStore);
224             memdb_g.apMemStore = 0;
225           }
226         }
227         break;
228       }
229     }
230     sqlite3_mutex_leave(pVfsMutex);
231   }else{
232     memdbEnter(p);
233   }
234   p->nRef--;
235   if( p->nRef<=0 ){
236     if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
237       sqlite3_free(p->aData);
238     }
239     memdbLeave(p);
240     sqlite3_mutex_free(p->pMutex);
241     sqlite3_free(p);
242   }else{
243     memdbLeave(p);
244   }
245   return SQLITE_OK;
246 }
247 
248 /*
249 ** Read data from an memdb-file.
250 */
memdbRead(sqlite3_file * pFile,void * zBuf,int iAmt,sqlite_int64 iOfst)251 static int memdbRead(
252   sqlite3_file *pFile,
253   void *zBuf,
254   int iAmt,
255   sqlite_int64 iOfst
256 ){
257   MemStore *p = ((MemFile*)pFile)->pStore;
258   memdbEnter(p);
259   if( iOfst+iAmt>p->sz ){
260     memset(zBuf, 0, iAmt);
261     if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
262     memdbLeave(p);
263     return SQLITE_IOERR_SHORT_READ;
264   }
265   memcpy(zBuf, p->aData+iOfst, iAmt);
266   memdbLeave(p);
267   return SQLITE_OK;
268 }
269 
270 /*
271 ** Try to enlarge the memory allocation to hold at least sz bytes
272 */
memdbEnlarge(MemStore * p,sqlite3_int64 newSz)273 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
274   unsigned char *pNew;
275   if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){
276     return SQLITE_FULL;
277   }
278   if( newSz>p->szMax ){
279     return SQLITE_FULL;
280   }
281   newSz *= 2;
282   if( newSz>p->szMax ) newSz = p->szMax;
283   pNew = sqlite3Realloc(p->aData, newSz);
284   if( pNew==0 ) return SQLITE_IOERR_NOMEM;
285   p->aData = pNew;
286   p->szAlloc = newSz;
287   return SQLITE_OK;
288 }
289 
290 /*
291 ** Write data to an memdb-file.
292 */
memdbWrite(sqlite3_file * pFile,const void * z,int iAmt,sqlite_int64 iOfst)293 static int memdbWrite(
294   sqlite3_file *pFile,
295   const void *z,
296   int iAmt,
297   sqlite_int64 iOfst
298 ){
299   MemStore *p = ((MemFile*)pFile)->pStore;
300   memdbEnter(p);
301   if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
302     /* Can't happen: memdbLock() will return SQLITE_READONLY before
303     ** reaching this point */
304     memdbLeave(p);
305     return SQLITE_IOERR_WRITE;
306   }
307   if( iOfst+iAmt>p->sz ){
308     int rc;
309     if( iOfst+iAmt>p->szAlloc
310      && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
311     ){
312       memdbLeave(p);
313       return rc;
314     }
315     if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
316     p->sz = iOfst+iAmt;
317   }
318   memcpy(p->aData+iOfst, z, iAmt);
319   memdbLeave(p);
320   return SQLITE_OK;
321 }
322 
323 /*
324 ** Truncate an memdb-file.
325 **
326 ** In rollback mode (which is always the case for memdb, as it does not
327 ** support WAL mode) the truncate() method is only used to reduce
328 ** the size of a file, never to increase the size.
329 */
memdbTruncate(sqlite3_file * pFile,sqlite_int64 size)330 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
331   MemStore *p = ((MemFile*)pFile)->pStore;
332   int rc = SQLITE_OK;
333   memdbEnter(p);
334   if( size>p->sz ){
335     /* This can only happen with a corrupt wal mode db */
336     rc = SQLITE_CORRUPT;
337   }else{
338     p->sz = size;
339   }
340   memdbLeave(p);
341   return rc;
342 }
343 
344 /*
345 ** Sync an memdb-file.
346 */
memdbSync(sqlite3_file * pFile,int flags)347 static int memdbSync(sqlite3_file *pFile, int flags){
348   UNUSED_PARAMETER(pFile);
349   UNUSED_PARAMETER(flags);
350   return SQLITE_OK;
351 }
352 
353 /*
354 ** Return the current file-size of an memdb-file.
355 */
memdbFileSize(sqlite3_file * pFile,sqlite_int64 * pSize)356 static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
357   MemStore *p = ((MemFile*)pFile)->pStore;
358   memdbEnter(p);
359   *pSize = p->sz;
360   memdbLeave(p);
361   return SQLITE_OK;
362 }
363 
364 /*
365 ** Lock an memdb-file.
366 */
memdbLock(sqlite3_file * pFile,int eLock)367 static int memdbLock(sqlite3_file *pFile, int eLock){
368   MemFile *pThis = (MemFile*)pFile;
369   MemStore *p = pThis->pStore;
370   int rc = SQLITE_OK;
371   if( eLock==pThis->eLock ) return SQLITE_OK;
372   memdbEnter(p);
373   if( eLock>SQLITE_LOCK_SHARED ){
374     if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
375       rc = SQLITE_READONLY;
376     }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
377       if( p->nWrLock ){
378         rc = SQLITE_BUSY;
379       }else{
380         p->nWrLock = 1;
381       }
382     }
383   }else if( eLock==SQLITE_LOCK_SHARED ){
384     if( pThis->eLock > SQLITE_LOCK_SHARED ){
385       assert( p->nWrLock==1 );
386       p->nWrLock = 0;
387     }else if( p->nWrLock ){
388       rc = SQLITE_BUSY;
389     }else{
390       p->nRdLock++;
391     }
392   }else{
393     assert( eLock==SQLITE_LOCK_NONE );
394     if( pThis->eLock>SQLITE_LOCK_SHARED ){
395       assert( p->nWrLock==1 );
396       p->nWrLock = 0;
397     }
398     assert( p->nRdLock>0 );
399     p->nRdLock--;
400   }
401   if( rc==SQLITE_OK ) pThis->eLock = eLock;
402   memdbLeave(p);
403   return rc;
404 }
405 
406 #if 0
407 /*
408 ** This interface is only used for crash recovery, which does not
409 ** occur on an in-memory database.
410 */
411 static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
412   *pResOut = 0;
413   return SQLITE_OK;
414 }
415 #endif
416 
417 
418 /*
419 ** File control method. For custom operations on an memdb-file.
420 */
memdbFileControl(sqlite3_file * pFile,int op,void * pArg)421 static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
422   MemStore *p = ((MemFile*)pFile)->pStore;
423   int rc = SQLITE_NOTFOUND;
424   memdbEnter(p);
425   if( op==SQLITE_FCNTL_VFSNAME ){
426     *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
427     rc = SQLITE_OK;
428   }
429   if( op==SQLITE_FCNTL_SIZE_LIMIT ){
430     sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
431     if( iLimit<p->sz ){
432       if( iLimit<0 ){
433         iLimit = p->szMax;
434       }else{
435         iLimit = p->sz;
436       }
437     }
438     p->szMax = iLimit;
439     *(sqlite3_int64*)pArg = iLimit;
440     rc = SQLITE_OK;
441   }
442   memdbLeave(p);
443   return rc;
444 }
445 
446 #if 0  /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
447 /*
448 ** Return the sector-size in bytes for an memdb-file.
449 */
450 static int memdbSectorSize(sqlite3_file *pFile){
451   return 1024;
452 }
453 #endif
454 
455 /*
456 ** Return the device characteristic flags supported by an memdb-file.
457 */
memdbDeviceCharacteristics(sqlite3_file * pFile)458 static int memdbDeviceCharacteristics(sqlite3_file *pFile){
459   UNUSED_PARAMETER(pFile);
460   return SQLITE_IOCAP_ATOMIC |
461          SQLITE_IOCAP_POWERSAFE_OVERWRITE |
462          SQLITE_IOCAP_SAFE_APPEND |
463          SQLITE_IOCAP_SEQUENTIAL;
464 }
465 
466 /* Fetch a page of a memory-mapped file */
memdbFetch(sqlite3_file * pFile,sqlite3_int64 iOfst,int iAmt,void ** pp)467 static int memdbFetch(
468   sqlite3_file *pFile,
469   sqlite3_int64 iOfst,
470   int iAmt,
471   void **pp
472 ){
473   MemStore *p = ((MemFile*)pFile)->pStore;
474   memdbEnter(p);
475   if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){
476     *pp = 0;
477   }else{
478     p->nMmap++;
479     *pp = (void*)(p->aData + iOfst);
480   }
481   memdbLeave(p);
482   return SQLITE_OK;
483 }
484 
485 /* Release a memory-mapped page */
memdbUnfetch(sqlite3_file * pFile,sqlite3_int64 iOfst,void * pPage)486 static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
487   MemStore *p = ((MemFile*)pFile)->pStore;
488   UNUSED_PARAMETER(iOfst);
489   UNUSED_PARAMETER(pPage);
490   memdbEnter(p);
491   p->nMmap--;
492   memdbLeave(p);
493   return SQLITE_OK;
494 }
495 
496 /*
497 ** Open an mem file handle.
498 */
memdbOpen(sqlite3_vfs * pVfs,const char * zName,sqlite3_file * pFd,int flags,int * pOutFlags)499 static int memdbOpen(
500   sqlite3_vfs *pVfs,
501   const char *zName,
502   sqlite3_file *pFd,
503   int flags,
504   int *pOutFlags
505 ){
506   MemFile *pFile = (MemFile*)pFd;
507   MemStore *p = 0;
508   int szName;
509   UNUSED_PARAMETER(pVfs);
510 
511   memset(pFile, 0, sizeof(*pFile));
512   szName = sqlite3Strlen30(zName);
513   if( szName>1 && zName[0]=='/' ){
514     int i;
515 #ifndef SQLITE_MUTEX_OMIT
516     sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
517 #endif
518     sqlite3_mutex_enter(pVfsMutex);
519     for(i=0; i<memdb_g.nMemStore; i++){
520       if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
521         p = memdb_g.apMemStore[i];
522         break;
523       }
524     }
525     if( p==0 ){
526       MemStore **apNew;
527       p = sqlite3Malloc( sizeof(*p) + szName + 3 );
528       if( p==0 ){
529         sqlite3_mutex_leave(pVfsMutex);
530         return SQLITE_NOMEM;
531       }
532       apNew = sqlite3Realloc(memdb_g.apMemStore,
533                              sizeof(apNew[0])*(memdb_g.nMemStore+1) );
534       if( apNew==0 ){
535         sqlite3_free(p);
536         sqlite3_mutex_leave(pVfsMutex);
537         return SQLITE_NOMEM;
538       }
539       apNew[memdb_g.nMemStore++] = p;
540       memdb_g.apMemStore = apNew;
541       memset(p, 0, sizeof(*p));
542       p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE;
543       p->szMax = sqlite3GlobalConfig.mxMemdbSize;
544       p->zFName = (char*)&p[1];
545       memcpy(p->zFName, zName, szName+1);
546       p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
547       if( p->pMutex==0 ){
548         memdb_g.nMemStore--;
549         sqlite3_free(p);
550         sqlite3_mutex_leave(pVfsMutex);
551         return SQLITE_NOMEM;
552       }
553       p->nRef = 1;
554       memdbEnter(p);
555     }else{
556       memdbEnter(p);
557       p->nRef++;
558     }
559     sqlite3_mutex_leave(pVfsMutex);
560   }else{
561     p = sqlite3Malloc( sizeof(*p) );
562     if( p==0 ){
563       return SQLITE_NOMEM;
564     }
565     memset(p, 0, sizeof(*p));
566     p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
567     p->szMax = sqlite3GlobalConfig.mxMemdbSize;
568   }
569   pFile->pStore = p;
570   if( pOutFlags!=0 ){
571     *pOutFlags = flags | SQLITE_OPEN_MEMORY;
572   }
573   pFd->pMethods = &memdb_io_methods;
574   memdbLeave(p);
575   return SQLITE_OK;
576 }
577 
578 #if 0 /* Only used to delete rollback journals, super-journals, and WAL
579       ** files, none of which exist in memdb.  So this routine is never used */
580 /*
581 ** Delete the file located at zPath. If the dirSync argument is true,
582 ** ensure the file-system modifications are synced to disk before
583 ** returning.
584 */
585 static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
586   return SQLITE_IOERR_DELETE;
587 }
588 #endif
589 
590 /*
591 ** Test for access permissions. Return true if the requested permission
592 ** is available, or false otherwise.
593 **
594 ** With memdb, no files ever exist on disk.  So always return false.
595 */
memdbAccess(sqlite3_vfs * pVfs,const char * zPath,int flags,int * pResOut)596 static int memdbAccess(
597   sqlite3_vfs *pVfs,
598   const char *zPath,
599   int flags,
600   int *pResOut
601 ){
602   UNUSED_PARAMETER(pVfs);
603   UNUSED_PARAMETER(zPath);
604   UNUSED_PARAMETER(flags);
605   *pResOut = 0;
606   return SQLITE_OK;
607 }
608 
609 /*
610 ** Populate buffer zOut with the full canonical pathname corresponding
611 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
612 ** of at least (INST_MAX_PATHNAME+1) bytes.
613 */
memdbFullPathname(sqlite3_vfs * pVfs,const char * zPath,int nOut,char * zOut)614 static int memdbFullPathname(
615   sqlite3_vfs *pVfs,
616   const char *zPath,
617   int nOut,
618   char *zOut
619 ){
620   UNUSED_PARAMETER(pVfs);
621   sqlite3_snprintf(nOut, zOut, "%s", zPath);
622   return SQLITE_OK;
623 }
624 
625 /*
626 ** Open the dynamic library located at zPath and return a handle.
627 */
memdbDlOpen(sqlite3_vfs * pVfs,const char * zPath)628 static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
629   return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
630 }
631 
632 /*
633 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
634 ** utf-8 string describing the most recent error encountered associated
635 ** with dynamic libraries.
636 */
memdbDlError(sqlite3_vfs * pVfs,int nByte,char * zErrMsg)637 static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
638   ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
639 }
640 
641 /*
642 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
643 */
memdbDlSym(sqlite3_vfs * pVfs,void * p,const char * zSym)644 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
645   return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
646 }
647 
648 /*
649 ** Close the dynamic library handle pHandle.
650 */
memdbDlClose(sqlite3_vfs * pVfs,void * pHandle)651 static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
652   ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
653 }
654 
655 /*
656 ** Populate the buffer pointed to by zBufOut with nByte bytes of
657 ** random data.
658 */
memdbRandomness(sqlite3_vfs * pVfs,int nByte,char * zBufOut)659 static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
660   return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
661 }
662 
663 /*
664 ** Sleep for nMicro microseconds. Return the number of microseconds
665 ** actually slept.
666 */
memdbSleep(sqlite3_vfs * pVfs,int nMicro)667 static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
668   return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
669 }
670 
671 #if 0  /* Never used.  Modern cores only call xCurrentTimeInt64() */
672 /*
673 ** Return the current time as a Julian Day number in *pTimeOut.
674 */
675 static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
676   return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
677 }
678 #endif
679 
memdbGetLastError(sqlite3_vfs * pVfs,int a,char * b)680 static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
681   return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
682 }
memdbCurrentTimeInt64(sqlite3_vfs * pVfs,sqlite3_int64 * p)683 static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
684   return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
685 }
686 
687 /*
688 ** Translate a database connection pointer and schema name into a
689 ** MemFile pointer.
690 */
memdbFromDbSchema(sqlite3 * db,const char * zSchema)691 static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
692   MemFile *p = 0;
693   MemStore *pStore;
694   int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
695   if( rc ) return 0;
696   if( p->base.pMethods!=&memdb_io_methods ) return 0;
697   pStore = p->pStore;
698   memdbEnter(pStore);
699   if( pStore->zFName!=0 ) p = 0;
700   memdbLeave(pStore);
701   return p;
702 }
703 
704 /*
705 ** Return the serialization of a database
706 */
sqlite3_serialize(sqlite3 * db,const char * zSchema,sqlite3_int64 * piSize,unsigned int mFlags)707 unsigned char *sqlite3_serialize(
708   sqlite3 *db,              /* The database connection */
709   const char *zSchema,      /* Which database within the connection */
710   sqlite3_int64 *piSize,    /* Write size here, if not NULL */
711   unsigned int mFlags       /* Maybe SQLITE_SERIALIZE_NOCOPY */
712 ){
713   MemFile *p;
714   int iDb;
715   Btree *pBt;
716   sqlite3_int64 sz;
717   int szPage = 0;
718   sqlite3_stmt *pStmt = 0;
719   unsigned char *pOut;
720   char *zSql;
721   int rc;
722 
723 #ifdef SQLITE_ENABLE_API_ARMOR
724   if( !sqlite3SafetyCheckOk(db) ){
725     (void)SQLITE_MISUSE_BKPT;
726     return 0;
727   }
728 #endif
729 
730   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
731   p = memdbFromDbSchema(db, zSchema);
732   iDb = sqlite3FindDbName(db, zSchema);
733   if( piSize ) *piSize = -1;
734   if( iDb<0 ) return 0;
735   if( p ){
736     MemStore *pStore = p->pStore;
737     assert( pStore->pMutex==0 );
738     if( piSize ) *piSize = pStore->sz;
739     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
740       pOut = pStore->aData;
741     }else{
742       pOut = sqlite3_malloc64( pStore->sz );
743       if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
744     }
745     return pOut;
746   }
747   pBt = db->aDb[iDb].pBt;
748   if( pBt==0 ) return 0;
749   szPage = sqlite3BtreeGetPageSize(pBt);
750   zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
751   rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
752   sqlite3_free(zSql);
753   if( rc ) return 0;
754   rc = sqlite3_step(pStmt);
755   if( rc!=SQLITE_ROW ){
756     pOut = 0;
757   }else{
758     sz = sqlite3_column_int64(pStmt, 0)*szPage;
759     if( piSize ) *piSize = sz;
760     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
761       pOut = 0;
762     }else{
763       pOut = sqlite3_malloc64( sz );
764       if( pOut ){
765         int nPage = sqlite3_column_int(pStmt, 0);
766         Pager *pPager = sqlite3BtreePager(pBt);
767         int pgno;
768         for(pgno=1; pgno<=nPage; pgno++){
769           DbPage *pPage = 0;
770           unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
771           rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
772           if( rc==SQLITE_OK ){
773             memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
774           }else{
775             memset(pTo, 0, szPage);
776           }
777           sqlite3PagerUnref(pPage);
778         }
779       }
780     }
781   }
782   sqlite3_finalize(pStmt);
783   return pOut;
784 }
785 
786 /* Convert zSchema to a MemDB and initialize its content.
787 */
sqlite3_deserialize(sqlite3 * db,const char * zSchema,unsigned char * pData,sqlite3_int64 szDb,sqlite3_int64 szBuf,unsigned mFlags)788 int sqlite3_deserialize(
789   sqlite3 *db,            /* The database connection */
790   const char *zSchema,    /* Which DB to reopen with the deserialization */
791   unsigned char *pData,   /* The serialized database content */
792   sqlite3_int64 szDb,     /* Number bytes in the deserialization */
793   sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
794   unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
795 ){
796   MemFile *p;
797   char *zSql;
798   sqlite3_stmt *pStmt = 0;
799   int rc;
800   int iDb;
801 
802 #ifdef SQLITE_ENABLE_API_ARMOR
803   if( !sqlite3SafetyCheckOk(db) ){
804     return SQLITE_MISUSE_BKPT;
805   }
806   if( szDb<0 ) return SQLITE_MISUSE_BKPT;
807   if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
808 #endif
809 
810   sqlite3_mutex_enter(db->mutex);
811   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
812   iDb = sqlite3FindDbName(db, zSchema);
813   testcase( iDb==1 );
814   if( iDb<2 && iDb!=0 ){
815     rc = SQLITE_ERROR;
816     goto end_deserialize;
817   }
818   zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
819   if( zSql==0 ){
820     rc = SQLITE_NOMEM;
821   }else{
822     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
823     sqlite3_free(zSql);
824   }
825   if( rc ) goto end_deserialize;
826   db->init.iDb = (u8)iDb;
827   db->init.reopenMemdb = 1;
828   rc = sqlite3_step(pStmt);
829   db->init.reopenMemdb = 0;
830   if( rc!=SQLITE_DONE ){
831     rc = SQLITE_ERROR;
832     goto end_deserialize;
833   }
834   p = memdbFromDbSchema(db, zSchema);
835   if( p==0 ){
836     rc = SQLITE_ERROR;
837   }else{
838     MemStore *pStore = p->pStore;
839     pStore->aData = pData;
840     pData = 0;
841     pStore->sz = szDb;
842     pStore->szAlloc = szBuf;
843     pStore->szMax = szBuf;
844     if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
845       pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
846     }
847     pStore->mFlags = mFlags;
848     rc = SQLITE_OK;
849   }
850 
851 end_deserialize:
852   sqlite3_finalize(pStmt);
853   if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
854     sqlite3_free(pData);
855   }
856   sqlite3_mutex_leave(db->mutex);
857   return rc;
858 }
859 
860 /*
861 ** This routine is called when the extension is loaded.
862 ** Register the new VFS.
863 */
sqlite3MemdbInit(void)864 int sqlite3MemdbInit(void){
865   sqlite3_vfs *pLower = sqlite3_vfs_find(0);
866   unsigned int sz;
867   if( NEVER(pLower==0) ) return SQLITE_ERROR;
868   sz = pLower->szOsFile;
869   memdb_vfs.pAppData = pLower;
870   /* The following conditional can only be true when compiled for
871   ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0.  We always leave
872   ** it in, to be safe, but it is marked as NO_TEST since there
873   ** is no way to reach it under most builds. */
874   if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
875   memdb_vfs.szOsFile = sz;
876   return sqlite3_vfs_register(&memdb_vfs, 0);
877 }
878 #endif /* SQLITE_OMIT_DESERIALIZE */
879