xref: /sqlite-3.40.0/src/memdb.c (revision 52d14078)
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 ** Global 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 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 };
157 
158 static const sqlite3_io_methods memdb_io_methods = {
159   3,                              /* iVersion */
160   memdbClose,                      /* xClose */
161   memdbRead,                       /* xRead */
162   memdbWrite,                      /* xWrite */
163   memdbTruncate,                   /* xTruncate */
164   memdbSync,                       /* xSync */
165   memdbFileSize,                   /* xFileSize */
166   memdbLock,                       /* xLock */
167   memdbLock,                       /* xUnlock - same as xLock in this case */
168   0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
169   memdbFileControl,                /* xFileControl */
170   0, /* memdbSectorSize,*/         /* xSectorSize */
171   memdbDeviceCharacteristics,      /* xDeviceCharacteristics */
172   0,                               /* xShmMap */
173   0,                               /* xShmLock */
174   0,                               /* xShmBarrier */
175   0,                               /* xShmUnmap */
176   memdbFetch,                      /* xFetch */
177   memdbUnfetch                     /* xUnfetch */
178 };
179 
180 /*
181 ** Enter/leave the mutex on a MemStore
182 */
183 static void memdbEnter(MemStore *p){
184   sqlite3_mutex_enter(p->pMutex);
185 }
186 static void memdbLeave(MemStore *p){
187   sqlite3_mutex_leave(p->pMutex);
188 }
189 
190 
191 
192 /*
193 ** Close an memdb-file.
194 ** Free the underlying MemStore object when its refcount drops to zero
195 ** or less.
196 */
197 static int memdbClose(sqlite3_file *pFile){
198   MemStore *p = ((MemFile*)pFile)->pStore;
199   if( p->zFName ){
200     int i;
201 #ifndef SQLITE_MUTEX_OMIT
202     sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
203 #endif
204     sqlite3_mutex_enter(pVfsMutex);
205     for(i=0; ALWAYS(i<memdb_g.nMemStore); i++){
206       if( memdb_g.apMemStore[i]==p ){
207         memdbEnter(p);
208         if( p->nRef==1 ){
209           memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore];
210           if( memdb_g.nMemStore==0 ){
211             sqlite3_free(memdb_g.apMemStore);
212             memdb_g.apMemStore = 0;
213           }
214         }
215         break;
216       }
217     }
218     sqlite3_mutex_leave(pVfsMutex);
219   }else{
220     memdbEnter(p);
221   }
222   p->nRef--;
223   if( p->nRef<=0 ){
224     if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
225       sqlite3_free(p->aData);
226     }
227     memdbLeave(p);
228     sqlite3_mutex_free(p->pMutex);
229     sqlite3_free(p);
230   }else{
231     memdbLeave(p);
232   }
233   return SQLITE_OK;
234 }
235 
236 /*
237 ** Read data from an memdb-file.
238 */
239 static int memdbRead(
240   sqlite3_file *pFile,
241   void *zBuf,
242   int iAmt,
243   sqlite_int64 iOfst
244 ){
245   MemStore *p = ((MemFile*)pFile)->pStore;
246   memdbEnter(p);
247   if( iOfst+iAmt>p->sz ){
248     memset(zBuf, 0, iAmt);
249     if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
250     memdbLeave(p);
251     return SQLITE_IOERR_SHORT_READ;
252   }
253   memcpy(zBuf, p->aData+iOfst, iAmt);
254   memdbLeave(p);
255   return SQLITE_OK;
256 }
257 
258 /*
259 ** Try to enlarge the memory allocation to hold at least sz bytes
260 */
261 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
262   unsigned char *pNew;
263   if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
264     return SQLITE_FULL;
265   }
266   if( newSz>p->szMax ){
267     return SQLITE_FULL;
268   }
269   newSz *= 2;
270   if( newSz>p->szMax ) newSz = p->szMax;
271   pNew = sqlite3Realloc(p->aData, newSz);
272   if( pNew==0 ) return SQLITE_IOERR_NOMEM;
273   p->aData = pNew;
274   p->szAlloc = newSz;
275   return SQLITE_OK;
276 }
277 
278 /*
279 ** Write data to an memdb-file.
280 */
281 static int memdbWrite(
282   sqlite3_file *pFile,
283   const void *z,
284   int iAmt,
285   sqlite_int64 iOfst
286 ){
287   MemStore *p = ((MemFile*)pFile)->pStore;
288   memdbEnter(p);
289   if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
290     /* Can't happen: memdbLock() will return SQLITE_READONLY before
291     ** reaching this point */
292     memdbLeave(p);
293     return SQLITE_IOERR_WRITE;
294   }
295   if( iOfst+iAmt>p->sz ){
296     int rc;
297     if( iOfst+iAmt>p->szAlloc
298      && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
299     ){
300       memdbLeave(p);
301       return rc;
302     }
303     if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
304     p->sz = iOfst+iAmt;
305   }
306   memcpy(p->aData+iOfst, z, iAmt);
307   memdbLeave(p);
308   return SQLITE_OK;
309 }
310 
311 /*
312 ** Truncate an memdb-file.
313 **
314 ** In rollback mode (which is always the case for memdb, as it does not
315 ** support WAL mode) the truncate() method is only used to reduce
316 ** the size of a file, never to increase the size.
317 */
318 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
319   MemStore *p = ((MemFile*)pFile)->pStore;
320   int rc = SQLITE_OK;
321   memdbEnter(p);
322   if( NEVER(size>p->sz) ){
323     rc = SQLITE_FULL;
324   }else{
325     p->sz = size;
326   }
327   memdbLeave(p);
328   return rc;
329 }
330 
331 /*
332 ** Sync an memdb-file.
333 */
334 static int memdbSync(sqlite3_file *pFile, int flags){
335   return SQLITE_OK;
336 }
337 
338 /*
339 ** Return the current file-size of an memdb-file.
340 */
341 static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
342   MemStore *p = ((MemFile*)pFile)->pStore;
343   memdbEnter(p);
344   *pSize = p->sz;
345   memdbLeave(p);
346   return SQLITE_OK;
347 }
348 
349 /*
350 ** Lock an memdb-file.
351 */
352 static int memdbLock(sqlite3_file *pFile, int eLock){
353   MemFile *pThis = (MemFile*)pFile;
354   MemStore *p = pThis->pStore;
355   int rc = SQLITE_OK;
356   if( eLock==pThis->eLock ) return SQLITE_OK;
357   memdbEnter(p);
358   if( eLock>SQLITE_LOCK_SHARED ){
359     if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
360       rc = SQLITE_READONLY;
361     }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
362       if( p->nWrLock ){
363         rc = SQLITE_BUSY;
364       }else{
365         p->nWrLock = 1;
366       }
367     }
368   }else if( eLock==SQLITE_LOCK_SHARED ){
369     if( pThis->eLock > SQLITE_LOCK_SHARED ){
370       assert( p->nWrLock==1 );
371       p->nWrLock = 0;
372     }else if( p->nWrLock ){
373       rc = SQLITE_BUSY;
374     }else{
375       p->nRdLock++;
376     }
377   }else{
378     assert( eLock==SQLITE_LOCK_NONE );
379     if( pThis->eLock>SQLITE_LOCK_SHARED ){
380       assert( p->nWrLock==1 );
381       p->nWrLock = 0;
382     }
383     assert( p->nRdLock>0 );
384     p->nRdLock--;
385   }
386   if( rc==SQLITE_OK ) pThis->eLock = eLock;
387   memdbLeave(p);
388   return rc;
389 }
390 
391 #if 0
392 /*
393 ** This interface is only used for crash recovery, which does not
394 ** occur on an in-memory database.
395 */
396 static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
397   *pResOut = 0;
398   return SQLITE_OK;
399 }
400 #endif
401 
402 
403 /*
404 ** File control method. For custom operations on an memdb-file.
405 */
406 static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
407   MemStore *p = ((MemFile*)pFile)->pStore;
408   int rc = SQLITE_NOTFOUND;
409   memdbEnter(p);
410   if( op==SQLITE_FCNTL_VFSNAME ){
411     *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
412     rc = SQLITE_OK;
413   }
414   if( op==SQLITE_FCNTL_SIZE_LIMIT ){
415     sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
416     if( iLimit<p->sz ){
417       if( iLimit<0 ){
418         iLimit = p->szMax;
419       }else{
420         iLimit = p->sz;
421       }
422     }
423     p->szMax = iLimit;
424     *(sqlite3_int64*)pArg = iLimit;
425     rc = SQLITE_OK;
426   }
427   memdbLeave(p);
428   return rc;
429 }
430 
431 #if 0  /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
432 /*
433 ** Return the sector-size in bytes for an memdb-file.
434 */
435 static int memdbSectorSize(sqlite3_file *pFile){
436   return 1024;
437 }
438 #endif
439 
440 /*
441 ** Return the device characteristic flags supported by an memdb-file.
442 */
443 static int memdbDeviceCharacteristics(sqlite3_file *pFile){
444   return SQLITE_IOCAP_ATOMIC |
445          SQLITE_IOCAP_POWERSAFE_OVERWRITE |
446          SQLITE_IOCAP_SAFE_APPEND |
447          SQLITE_IOCAP_SEQUENTIAL;
448 }
449 
450 /* Fetch a page of a memory-mapped file */
451 static int memdbFetch(
452   sqlite3_file *pFile,
453   sqlite3_int64 iOfst,
454   int iAmt,
455   void **pp
456 ){
457   MemStore *p = ((MemFile*)pFile)->pStore;
458   memdbEnter(p);
459   if( iOfst+iAmt>p->sz ){
460     *pp = 0;
461   }else{
462     p->nMmap++;
463     *pp = (void*)(p->aData + iOfst);
464   }
465   memdbLeave(p);
466   return SQLITE_OK;
467 }
468 
469 /* Release a memory-mapped page */
470 static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
471   MemStore *p = ((MemFile*)pFile)->pStore;
472   memdbEnter(p);
473   p->nMmap--;
474   memdbLeave(p);
475   return SQLITE_OK;
476 }
477 
478 /*
479 ** Open an mem file handle.
480 */
481 static int memdbOpen(
482   sqlite3_vfs *pVfs,
483   const char *zName,
484   sqlite3_file *pFd,
485   int flags,
486   int *pOutFlags
487 ){
488   MemFile *pFile = (MemFile*)pFd;
489   MemStore *p = 0;
490   int szName;
491   if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
492     return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
493   }
494   memset(pFile, 0, sizeof(*p));
495   szName = sqlite3Strlen30(zName);
496   if( szName>1 && zName[0]=='/' ){
497     int i;
498 #ifndef SQLITE_MUTEX_OMIT
499     sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
500 #endif
501     sqlite3_mutex_enter(pVfsMutex);
502     for(i=0; i<memdb_g.nMemStore; i++){
503       if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
504         p = memdb_g.apMemStore[i];
505         break;
506       }
507     }
508     if( p==0 ){
509       MemStore **apNew;
510       p = sqlite3Malloc( sizeof(*p) + szName + 3 );
511       if( p==0 ){
512         sqlite3_mutex_leave(pVfsMutex);
513         return SQLITE_NOMEM;
514       }
515       apNew = sqlite3Realloc(memdb_g.apMemStore,
516                              sizeof(apNew[0])*(memdb_g.nMemStore+1) );
517       if( apNew==0 ){
518         sqlite3_free(p);
519         sqlite3_mutex_leave(pVfsMutex);
520         return SQLITE_NOMEM;
521       }
522       apNew[memdb_g.nMemStore++] = p;
523       memdb_g.apMemStore = apNew;
524       memset(p, 0, sizeof(*p));
525       p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE;
526       p->szMax = sqlite3GlobalConfig.mxMemdbSize;
527       p->zFName = (char*)&p[1];
528       memcpy(p->zFName, zName, szName+1);
529       p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
530       if( p->pMutex==0 ){
531         memdb_g.nMemStore--;
532         sqlite3_free(p);
533         sqlite3_mutex_leave(pVfsMutex);
534         return SQLITE_NOMEM;
535       }
536       p->nRef = 1;
537       memdbEnter(p);
538     }else{
539       memdbEnter(p);
540       p->nRef++;
541     }
542     sqlite3_mutex_leave(pVfsMutex);
543   }else{
544     p = sqlite3Malloc( sizeof(*p) );
545     if( p==0 ){
546       return SQLITE_NOMEM;
547     }
548     memset(p, 0, sizeof(*p));
549     p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
550     p->szMax = sqlite3GlobalConfig.mxMemdbSize;
551   }
552   pFile->pStore = p;
553   assert( pOutFlags!=0 );  /* True because flags==SQLITE_OPEN_MAIN_DB */
554   *pOutFlags = flags | SQLITE_OPEN_MEMORY;
555   pFd->pMethods = &memdb_io_methods;
556   memdbLeave(p);
557   return SQLITE_OK;
558 }
559 
560 #if 0 /* Only used to delete rollback journals, super-journals, and WAL
561       ** files, none of which exist in memdb.  So this routine is never used */
562 /*
563 ** Delete the file located at zPath. If the dirSync argument is true,
564 ** ensure the file-system modifications are synced to disk before
565 ** returning.
566 */
567 static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
568   return SQLITE_IOERR_DELETE;
569 }
570 #endif
571 
572 /*
573 ** Test for access permissions. Return true if the requested permission
574 ** is available, or false otherwise.
575 **
576 ** With memdb, no files ever exist on disk.  So always return false.
577 */
578 static int memdbAccess(
579   sqlite3_vfs *pVfs,
580   const char *zPath,
581   int flags,
582   int *pResOut
583 ){
584   *pResOut = 0;
585   return SQLITE_OK;
586 }
587 
588 /*
589 ** Populate buffer zOut with the full canonical pathname corresponding
590 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
591 ** of at least (INST_MAX_PATHNAME+1) bytes.
592 */
593 static int memdbFullPathname(
594   sqlite3_vfs *pVfs,
595   const char *zPath,
596   int nOut,
597   char *zOut
598 ){
599   sqlite3_snprintf(nOut, zOut, "%s", zPath);
600   return SQLITE_OK;
601 }
602 
603 /*
604 ** Open the dynamic library located at zPath and return a handle.
605 */
606 static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
607   return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
608 }
609 
610 /*
611 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
612 ** utf-8 string describing the most recent error encountered associated
613 ** with dynamic libraries.
614 */
615 static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
616   ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
617 }
618 
619 /*
620 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
621 */
622 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
623   return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
624 }
625 
626 /*
627 ** Close the dynamic library handle pHandle.
628 */
629 static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
630   ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
631 }
632 
633 /*
634 ** Populate the buffer pointed to by zBufOut with nByte bytes of
635 ** random data.
636 */
637 static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
638   return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
639 }
640 
641 /*
642 ** Sleep for nMicro microseconds. Return the number of microseconds
643 ** actually slept.
644 */
645 static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
646   return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
647 }
648 
649 #if 0  /* Never used.  Modern cores only call xCurrentTimeInt64() */
650 /*
651 ** Return the current time as a Julian Day number in *pTimeOut.
652 */
653 static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
654   return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
655 }
656 #endif
657 
658 static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
659   return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
660 }
661 static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
662   return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
663 }
664 
665 /*
666 ** Translate a database connection pointer and schema name into a
667 ** MemFile pointer.
668 */
669 static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
670   MemFile *p = 0;
671   MemStore *pStore;
672   int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
673   if( rc ) return 0;
674   if( p->base.pMethods!=&memdb_io_methods ) return 0;
675   pStore = p->pStore;
676   memdbEnter(pStore);
677   if( pStore->zFName!=0 ) p = 0;
678   memdbLeave(pStore);
679   return p;
680 }
681 
682 /*
683 ** Return the serialization of a database
684 */
685 unsigned char *sqlite3_serialize(
686   sqlite3 *db,              /* The database connection */
687   const char *zSchema,      /* Which database within the connection */
688   sqlite3_int64 *piSize,    /* Write size here, if not NULL */
689   unsigned int mFlags       /* Maybe SQLITE_SERIALIZE_NOCOPY */
690 ){
691   MemFile *p;
692   int iDb;
693   Btree *pBt;
694   sqlite3_int64 sz;
695   int szPage = 0;
696   sqlite3_stmt *pStmt = 0;
697   unsigned char *pOut;
698   char *zSql;
699   int rc;
700 
701 #ifdef SQLITE_ENABLE_API_ARMOR
702   if( !sqlite3SafetyCheckOk(db) ){
703     (void)SQLITE_MISUSE_BKPT;
704     return 0;
705   }
706 #endif
707 
708   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
709   p = memdbFromDbSchema(db, zSchema);
710   iDb = sqlite3FindDbName(db, zSchema);
711   if( piSize ) *piSize = -1;
712   if( iDb<0 ) return 0;
713   if( p ){
714     MemStore *pStore = p->pStore;
715     assert( pStore->pMutex==0 );
716     if( piSize ) *piSize = pStore->sz;
717     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
718       pOut = pStore->aData;
719     }else{
720       pOut = sqlite3_malloc64( pStore->sz );
721       if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
722     }
723     return pOut;
724   }
725   pBt = db->aDb[iDb].pBt;
726   if( pBt==0 ) return 0;
727   szPage = sqlite3BtreeGetPageSize(pBt);
728   zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
729   rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
730   sqlite3_free(zSql);
731   if( rc ) return 0;
732   rc = sqlite3_step(pStmt);
733   if( rc!=SQLITE_ROW ){
734     pOut = 0;
735   }else{
736     sz = sqlite3_column_int64(pStmt, 0)*szPage;
737     if( piSize ) *piSize = sz;
738     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
739       pOut = 0;
740     }else{
741       pOut = sqlite3_malloc64( sz );
742       if( pOut ){
743         int nPage = sqlite3_column_int(pStmt, 0);
744         Pager *pPager = sqlite3BtreePager(pBt);
745         int pgno;
746         for(pgno=1; pgno<=nPage; pgno++){
747           DbPage *pPage = 0;
748           unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
749           rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
750           if( rc==SQLITE_OK ){
751             memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
752           }else{
753             memset(pTo, 0, szPage);
754           }
755           sqlite3PagerUnref(pPage);
756         }
757       }
758     }
759   }
760   sqlite3_finalize(pStmt);
761   return pOut;
762 }
763 
764 /* Convert zSchema to a MemDB and initialize its content.
765 */
766 int sqlite3_deserialize(
767   sqlite3 *db,            /* The database connection */
768   const char *zSchema,    /* Which DB to reopen with the deserialization */
769   unsigned char *pData,   /* The serialized database content */
770   sqlite3_int64 szDb,     /* Number bytes in the deserialization */
771   sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
772   unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
773 ){
774   MemFile *p;
775   char *zSql;
776   sqlite3_stmt *pStmt = 0;
777   int rc;
778   int iDb;
779 
780 #ifdef SQLITE_ENABLE_API_ARMOR
781   if( !sqlite3SafetyCheckOk(db) ){
782     return SQLITE_MISUSE_BKPT;
783   }
784   if( szDb<0 ) return SQLITE_MISUSE_BKPT;
785   if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
786 #endif
787 
788   sqlite3_mutex_enter(db->mutex);
789   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
790   iDb = sqlite3FindDbName(db, zSchema);
791   if( iDb<0 ){
792     rc = SQLITE_ERROR;
793     goto end_deserialize;
794   }
795   zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
796   if( zSql==0 ){
797     rc = SQLITE_NOMEM;
798   }else{
799     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
800     sqlite3_free(zSql);
801   }
802   if( rc ) goto end_deserialize;
803   db->init.iDb = (u8)iDb;
804   db->init.reopenMemdb = 1;
805   rc = sqlite3_step(pStmt);
806   db->init.reopenMemdb = 0;
807   if( rc!=SQLITE_DONE ){
808     rc = SQLITE_ERROR;
809     goto end_deserialize;
810   }
811   p = memdbFromDbSchema(db, zSchema);
812   if( p==0 ){
813     rc = SQLITE_ERROR;
814   }else{
815     MemStore *pStore = p->pStore;
816     pStore->aData = pData;
817     pData = 0;
818     pStore->sz = szDb;
819     pStore->szAlloc = szBuf;
820     pStore->szMax = szBuf;
821     if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
822       pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
823     }
824     pStore->mFlags = mFlags;
825     rc = SQLITE_OK;
826   }
827 
828 end_deserialize:
829   sqlite3_finalize(pStmt);
830   if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
831     sqlite3_free(pData);
832   }
833   sqlite3_mutex_leave(db->mutex);
834   return rc;
835 }
836 
837 /*
838 ** This routine is called when the extension is loaded.
839 ** Register the new VFS.
840 */
841 int sqlite3MemdbInit(void){
842   sqlite3_vfs *pLower = sqlite3_vfs_find(0);
843   int sz = pLower->szOsFile;
844   memdb_vfs.pAppData = pLower;
845   /* The following conditional can only be true when compiled for
846   ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0.  We always leave
847   ** it in, to be safe, but it is marked as NO_TEST since there
848   ** is no way to reach it under most builds. */
849   if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
850   memdb_vfs.szOsFile = sz;
851   return sqlite3_vfs_register(&memdb_vfs, 0);
852 }
853 #endif /* SQLITE_OMIT_DESERIALIZE */
854