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 file implements an in-memory VFS. A database is held as a contiguous
16 ** This file also implements interface sqlite3_serialize() and
17 ** sqlite3_deserialize().
19 #include "sqliteInt.h"
20 #ifndef SQLITE_OMIT_DESERIALIZE
23 ** Forward declaration of objects used by this utility
25 typedef struct sqlite3_vfs MemVfs
;
26 typedef struct MemFile MemFile
;
27 typedef struct MemStore MemStore
;
29 /* Access to a lower-level VFS that (might) implement dynamic loading,
30 ** access to randomness, etc.
32 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
34 /* Storage for a memdb file.
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
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.
47 ** Separate memdb objects are created using a name that does not begin
48 ** with "/" or using sqlite3_deserialize().
50 ** Access rules for shared MemStore objects:
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[].
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[].
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[].
66 ** * The .aData pointer has the added requirement that it can can only
67 ** be changed (for resizing) when nMmap is zero.
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 */
86 sqlite3_file base
; /* IO methods */
87 MemStore
*pStore
; /* The storage */
88 int eLock
; /* Most recent lock against this file */
92 ** File-scope variables for holding the memdb files that are accessible
93 ** to multiple database connections in separate threads.
95 ** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object.
98 int nMemStore
; /* Number of shared MemStore objects */
99 MemStore
**apMemStore
; /* Array of all shared MemStore objects */
103 ** Methods for MemFile
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 memdbUnlock(sqlite3_file
*, int);
113 /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
114 static int memdbFileControl(sqlite3_file
*, int op
, void *pArg
);
115 /* static int memdbSectorSize(sqlite3_file*); // not used */
116 static int memdbDeviceCharacteristics(sqlite3_file
*);
117 static int memdbFetch(sqlite3_file
*, sqlite3_int64 iOfst
, int iAmt
, void **pp
);
118 static int memdbUnfetch(sqlite3_file
*, sqlite3_int64 iOfst
, void *p
);
121 ** Methods for MemVfs
123 static int memdbOpen(sqlite3_vfs
*, const char *, sqlite3_file
*, int , int *);
124 /* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
125 static int memdbAccess(sqlite3_vfs
*, const char *zName
, int flags
, int *);
126 static int memdbFullPathname(sqlite3_vfs
*, const char *zName
, int, char *zOut
);
127 static void *memdbDlOpen(sqlite3_vfs
*, const char *zFilename
);
128 static void memdbDlError(sqlite3_vfs
*, int nByte
, char *zErrMsg
);
129 static void (*memdbDlSym(sqlite3_vfs
*pVfs
, void *p
, const char*zSym
))(void);
130 static void memdbDlClose(sqlite3_vfs
*, void*);
131 static int memdbRandomness(sqlite3_vfs
*, int nByte
, char *zOut
);
132 static int memdbSleep(sqlite3_vfs
*, int microseconds
);
133 /* static int memdbCurrentTime(sqlite3_vfs*, double*); */
134 static int memdbGetLastError(sqlite3_vfs
*, int, char *);
135 static int memdbCurrentTimeInt64(sqlite3_vfs
*, sqlite3_int64
*);
137 static sqlite3_vfs memdb_vfs
= {
139 0, /* szOsFile (set when registered) */
140 1024, /* mxPathname */
143 0, /* pAppData (set when registered) */
144 memdbOpen
, /* xOpen */
145 0, /* memdbDelete, */ /* xDelete */
146 memdbAccess
, /* xAccess */
147 memdbFullPathname
, /* xFullPathname */
148 memdbDlOpen
, /* xDlOpen */
149 memdbDlError
, /* xDlError */
150 memdbDlSym
, /* xDlSym */
151 memdbDlClose
, /* xDlClose */
152 memdbRandomness
, /* xRandomness */
153 memdbSleep
, /* xSleep */
154 0, /* memdbCurrentTime, */ /* xCurrentTime */
155 memdbGetLastError
, /* xGetLastError */
156 memdbCurrentTimeInt64
, /* xCurrentTimeInt64 */
157 0, /* xSetSystemCall */
158 0, /* xGetSystemCall */
159 0, /* xNextSystemCall */
162 static const sqlite3_io_methods memdb_io_methods
= {
164 memdbClose
, /* xClose */
165 memdbRead
, /* xRead */
166 memdbWrite
, /* xWrite */
167 memdbTruncate
, /* xTruncate */
168 memdbSync
, /* xSync */
169 memdbFileSize
, /* xFileSize */
170 memdbLock
, /* xLock */
171 memdbUnlock
, /* xUnlock */
172 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
173 memdbFileControl
, /* xFileControl */
174 0, /* memdbSectorSize,*/ /* xSectorSize */
175 memdbDeviceCharacteristics
, /* xDeviceCharacteristics */
180 memdbFetch
, /* xFetch */
181 memdbUnfetch
/* xUnfetch */
185 ** Enter/leave the mutex on a MemStore
187 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
188 static void memdbEnter(MemStore
*p
){
191 static void memdbLeave(MemStore
*p
){
195 static void memdbEnter(MemStore
*p
){
196 sqlite3_mutex_enter(p
->pMutex
);
198 static void memdbLeave(MemStore
*p
){
199 sqlite3_mutex_leave(p
->pMutex
);
206 ** Close an memdb-file.
207 ** Free the underlying MemStore object when its refcount drops to zero
210 static int memdbClose(sqlite3_file
*pFile
){
211 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
214 #ifndef SQLITE_MUTEX_OMIT
215 sqlite3_mutex
*pVfsMutex
= sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1
);
217 sqlite3_mutex_enter(pVfsMutex
);
218 for(i
=0; ALWAYS(i
<memdb_g
.nMemStore
); i
++){
219 if( memdb_g
.apMemStore
[i
]==p
){
222 memdb_g
.apMemStore
[i
] = memdb_g
.apMemStore
[--memdb_g
.nMemStore
];
223 if( memdb_g
.nMemStore
==0 ){
224 sqlite3_free(memdb_g
.apMemStore
);
225 memdb_g
.apMemStore
= 0;
231 sqlite3_mutex_leave(pVfsMutex
);
237 if( p
->mFlags
& SQLITE_DESERIALIZE_FREEONCLOSE
){
238 sqlite3_free(p
->aData
);
241 sqlite3_mutex_free(p
->pMutex
);
250 ** Read data from an memdb-file.
252 static int memdbRead(
258 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
260 if( iOfst
+iAmt
>p
->sz
){
261 memset(zBuf
, 0, iAmt
);
262 if( iOfst
<p
->sz
) memcpy(zBuf
, p
->aData
+iOfst
, p
->sz
- iOfst
);
264 return SQLITE_IOERR_SHORT_READ
;
266 memcpy(zBuf
, p
->aData
+iOfst
, iAmt
);
272 ** Try to enlarge the memory allocation to hold at least sz bytes
274 static int memdbEnlarge(MemStore
*p
, sqlite3_int64 newSz
){
276 if( (p
->mFlags
& SQLITE_DESERIALIZE_RESIZEABLE
)==0 || NEVER(p
->nMmap
>0) ){
279 if( newSz
>p
->szMax
){
283 if( newSz
>p
->szMax
) newSz
= p
->szMax
;
284 pNew
= sqlite3Realloc(p
->aData
, newSz
);
285 if( pNew
==0 ) return SQLITE_IOERR_NOMEM
;
292 ** Write data to an memdb-file.
294 static int memdbWrite(
300 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
302 if( NEVER(p
->mFlags
& SQLITE_DESERIALIZE_READONLY
) ){
303 /* Can't happen: memdbLock() will return SQLITE_READONLY before
304 ** reaching this point */
306 return SQLITE_IOERR_WRITE
;
308 if( iOfst
+iAmt
>p
->sz
){
310 if( iOfst
+iAmt
>p
->szAlloc
311 && (rc
= memdbEnlarge(p
, iOfst
+iAmt
))!=SQLITE_OK
316 if( iOfst
>p
->sz
) memset(p
->aData
+p
->sz
, 0, iOfst
-p
->sz
);
319 memcpy(p
->aData
+iOfst
, z
, iAmt
);
325 ** Truncate an memdb-file.
327 ** In rollback mode (which is always the case for memdb, as it does not
328 ** support WAL mode) the truncate() method is only used to reduce
329 ** the size of a file, never to increase the size.
331 static int memdbTruncate(sqlite3_file
*pFile
, sqlite_int64 size
){
332 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
336 /* This can only happen with a corrupt wal mode db */
346 ** Sync an memdb-file.
348 static int memdbSync(sqlite3_file
*pFile
, int flags
){
349 UNUSED_PARAMETER(pFile
);
350 UNUSED_PARAMETER(flags
);
355 ** Return the current file-size of an memdb-file.
357 static int memdbFileSize(sqlite3_file
*pFile
, sqlite_int64
*pSize
){
358 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
366 ** Lock an memdb-file.
368 static int memdbLock(sqlite3_file
*pFile
, int eLock
){
369 MemFile
*pThis
= (MemFile
*)pFile
;
370 MemStore
*p
= pThis
->pStore
;
372 if( eLock
<=pThis
->eLock
) return SQLITE_OK
;
375 assert( p
->nWrLock
==0 || p
->nWrLock
==1 );
376 assert( pThis
->eLock
<=SQLITE_LOCK_SHARED
|| p
->nWrLock
==1 );
377 assert( pThis
->eLock
==SQLITE_LOCK_NONE
|| p
->nRdLock
>=1 );
379 if( eLock
>SQLITE_LOCK_SHARED
&& (p
->mFlags
& SQLITE_DESERIALIZE_READONLY
) ){
380 rc
= SQLITE_READONLY
;
383 case SQLITE_LOCK_SHARED
: {
384 assert( pThis
->eLock
==SQLITE_LOCK_NONE
);
393 case SQLITE_LOCK_RESERVED
:
394 case SQLITE_LOCK_PENDING
: {
395 assert( pThis
->eLock
>=SQLITE_LOCK_SHARED
);
396 if( ALWAYS(pThis
->eLock
==SQLITE_LOCK_SHARED
) ){
407 assert( eLock
==SQLITE_LOCK_EXCLUSIVE
);
408 assert( pThis
->eLock
>=SQLITE_LOCK_SHARED
);
411 }else if( pThis
->eLock
==SQLITE_LOCK_SHARED
){
418 if( rc
==SQLITE_OK
) pThis
->eLock
= eLock
;
424 ** Unlock an memdb-file.
426 static int memdbUnlock(sqlite3_file
*pFile
, int eLock
){
427 MemFile
*pThis
= (MemFile
*)pFile
;
428 MemStore
*p
= pThis
->pStore
;
429 if( eLock
>=pThis
->eLock
) return SQLITE_OK
;
432 assert( eLock
==SQLITE_LOCK_SHARED
|| eLock
==SQLITE_LOCK_NONE
);
433 if( eLock
==SQLITE_LOCK_SHARED
){
434 if( ALWAYS(pThis
->eLock
>SQLITE_LOCK_SHARED
) ){
438 if( pThis
->eLock
>SQLITE_LOCK_SHARED
){
444 pThis
->eLock
= eLock
;
451 ** This interface is only used for crash recovery, which does not
452 ** occur on an in-memory database.
454 static int memdbCheckReservedLock(sqlite3_file
*pFile
, int *pResOut
){
462 ** File control method. For custom operations on an memdb-file.
464 static int memdbFileControl(sqlite3_file
*pFile
, int op
, void *pArg
){
465 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
466 int rc
= SQLITE_NOTFOUND
;
468 if( op
==SQLITE_FCNTL_VFSNAME
){
469 *(char**)pArg
= sqlite3_mprintf("memdb(%p,%lld)", p
->aData
, p
->sz
);
472 if( op
==SQLITE_FCNTL_SIZE_LIMIT
){
473 sqlite3_int64 iLimit
= *(sqlite3_int64
*)pArg
;
482 *(sqlite3_int64
*)pArg
= iLimit
;
489 #if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
491 ** Return the sector-size in bytes for an memdb-file.
493 static int memdbSectorSize(sqlite3_file
*pFile
){
499 ** Return the device characteristic flags supported by an memdb-file.
501 static int memdbDeviceCharacteristics(sqlite3_file
*pFile
){
502 UNUSED_PARAMETER(pFile
);
503 return SQLITE_IOCAP_ATOMIC
|
504 SQLITE_IOCAP_POWERSAFE_OVERWRITE
|
505 SQLITE_IOCAP_SAFE_APPEND
|
506 SQLITE_IOCAP_SEQUENTIAL
;
509 /* Fetch a page of a memory-mapped file */
510 static int memdbFetch(
516 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
518 if( iOfst
+iAmt
>p
->sz
|| (p
->mFlags
& SQLITE_DESERIALIZE_RESIZEABLE
)!=0 ){
522 *pp
= (void*)(p
->aData
+ iOfst
);
528 /* Release a memory-mapped page */
529 static int memdbUnfetch(sqlite3_file
*pFile
, sqlite3_int64 iOfst
, void *pPage
){
530 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
531 UNUSED_PARAMETER(iOfst
);
532 UNUSED_PARAMETER(pPage
);
540 ** Open an mem file handle.
542 static int memdbOpen(
549 MemFile
*pFile
= (MemFile
*)pFd
;
552 UNUSED_PARAMETER(pVfs
);
554 memset(pFile
, 0, sizeof(*pFile
));
555 szName
= sqlite3Strlen30(zName
);
556 if( szName
>1 && (zName
[0]=='/' || zName
[0]=='\\') ){
558 #ifndef SQLITE_MUTEX_OMIT
559 sqlite3_mutex
*pVfsMutex
= sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1
);
561 sqlite3_mutex_enter(pVfsMutex
);
562 for(i
=0; i
<memdb_g
.nMemStore
; i
++){
563 if( strcmp(memdb_g
.apMemStore
[i
]->zFName
,zName
)==0 ){
564 p
= memdb_g
.apMemStore
[i
];
570 p
= sqlite3Malloc( sizeof(*p
) + szName
+ 3 );
572 sqlite3_mutex_leave(pVfsMutex
);
575 apNew
= sqlite3Realloc(memdb_g
.apMemStore
,
576 sizeof(apNew
[0])*(memdb_g
.nMemStore
+1) );
579 sqlite3_mutex_leave(pVfsMutex
);
582 apNew
[memdb_g
.nMemStore
++] = p
;
583 memdb_g
.apMemStore
= apNew
;
584 memset(p
, 0, sizeof(*p
));
585 p
->mFlags
= SQLITE_DESERIALIZE_RESIZEABLE
|SQLITE_DESERIALIZE_FREEONCLOSE
;
586 p
->szMax
= sqlite3GlobalConfig
.mxMemdbSize
;
587 p
->zFName
= (char*)&p
[1];
588 memcpy(p
->zFName
, zName
, szName
+1);
589 p
->pMutex
= sqlite3_mutex_alloc(SQLITE_MUTEX_FAST
);
593 sqlite3_mutex_leave(pVfsMutex
);
602 sqlite3_mutex_leave(pVfsMutex
);
604 p
= sqlite3Malloc( sizeof(*p
) );
608 memset(p
, 0, sizeof(*p
));
609 p
->mFlags
= SQLITE_DESERIALIZE_RESIZEABLE
| SQLITE_DESERIALIZE_FREEONCLOSE
;
610 p
->szMax
= sqlite3GlobalConfig
.mxMemdbSize
;
614 *pOutFlags
= flags
| SQLITE_OPEN_MEMORY
;
616 pFd
->pMethods
= &memdb_io_methods
;
621 #if 0 /* Only used to delete rollback journals, super-journals, and WAL
622 ** files, none of which exist in memdb. So this routine is never used */
624 ** Delete the file located at zPath. If the dirSync argument is true,
625 ** ensure the file-system modifications are synced to disk before
628 static int memdbDelete(sqlite3_vfs
*pVfs
, const char *zPath
, int dirSync
){
629 return SQLITE_IOERR_DELETE
;
634 ** Test for access permissions. Return true if the requested permission
635 ** is available, or false otherwise.
637 ** With memdb, no files ever exist on disk. So always return false.
639 static int memdbAccess(
645 UNUSED_PARAMETER(pVfs
);
646 UNUSED_PARAMETER(zPath
);
647 UNUSED_PARAMETER(flags
);
653 ** Populate buffer zOut with the full canonical pathname corresponding
654 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
655 ** of at least (INST_MAX_PATHNAME+1) bytes.
657 static int memdbFullPathname(
663 UNUSED_PARAMETER(pVfs
);
664 sqlite3_snprintf(nOut
, zOut
, "%s", zPath
);
669 ** Open the dynamic library located at zPath and return a handle.
671 static void *memdbDlOpen(sqlite3_vfs
*pVfs
, const char *zPath
){
672 return ORIGVFS(pVfs
)->xDlOpen(ORIGVFS(pVfs
), zPath
);
676 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
677 ** utf-8 string describing the most recent error encountered associated
678 ** with dynamic libraries.
680 static void memdbDlError(sqlite3_vfs
*pVfs
, int nByte
, char *zErrMsg
){
681 ORIGVFS(pVfs
)->xDlError(ORIGVFS(pVfs
), nByte
, zErrMsg
);
685 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
687 static void (*memdbDlSym(sqlite3_vfs
*pVfs
, void *p
, const char *zSym
))(void){
688 return ORIGVFS(pVfs
)->xDlSym(ORIGVFS(pVfs
), p
, zSym
);
692 ** Close the dynamic library handle pHandle.
694 static void memdbDlClose(sqlite3_vfs
*pVfs
, void *pHandle
){
695 ORIGVFS(pVfs
)->xDlClose(ORIGVFS(pVfs
), pHandle
);
699 ** Populate the buffer pointed to by zBufOut with nByte bytes of
702 static int memdbRandomness(sqlite3_vfs
*pVfs
, int nByte
, char *zBufOut
){
703 return ORIGVFS(pVfs
)->xRandomness(ORIGVFS(pVfs
), nByte
, zBufOut
);
707 ** Sleep for nMicro microseconds. Return the number of microseconds
710 static int memdbSleep(sqlite3_vfs
*pVfs
, int nMicro
){
711 return ORIGVFS(pVfs
)->xSleep(ORIGVFS(pVfs
), nMicro
);
714 #if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
716 ** Return the current time as a Julian Day number in *pTimeOut.
718 static int memdbCurrentTime(sqlite3_vfs
*pVfs
, double *pTimeOut
){
719 return ORIGVFS(pVfs
)->xCurrentTime(ORIGVFS(pVfs
), pTimeOut
);
723 static int memdbGetLastError(sqlite3_vfs
*pVfs
, int a
, char *b
){
724 return ORIGVFS(pVfs
)->xGetLastError(ORIGVFS(pVfs
), a
, b
);
726 static int memdbCurrentTimeInt64(sqlite3_vfs
*pVfs
, sqlite3_int64
*p
){
727 return ORIGVFS(pVfs
)->xCurrentTimeInt64(ORIGVFS(pVfs
), p
);
731 ** Translate a database connection pointer and schema name into a
734 static MemFile
*memdbFromDbSchema(sqlite3
*db
, const char *zSchema
){
737 int rc
= sqlite3_file_control(db
, zSchema
, SQLITE_FCNTL_FILE_POINTER
, &p
);
739 if( p
->base
.pMethods
!=&memdb_io_methods
) return 0;
742 if( pStore
->zFName
!=0 ) p
= 0;
748 ** Return the serialization of a database
750 unsigned char *sqlite3_serialize(
751 sqlite3
*db
, /* The database connection */
752 const char *zSchema
, /* Which database within the connection */
753 sqlite3_int64
*piSize
, /* Write size here, if not NULL */
754 unsigned int mFlags
/* Maybe SQLITE_SERIALIZE_NOCOPY */
761 sqlite3_stmt
*pStmt
= 0;
766 #ifdef SQLITE_ENABLE_API_ARMOR
767 if( !sqlite3SafetyCheckOk(db
) ){
768 (void)SQLITE_MISUSE_BKPT
;
773 if( zSchema
==0 ) zSchema
= db
->aDb
[0].zDbSName
;
774 p
= memdbFromDbSchema(db
, zSchema
);
775 iDb
= sqlite3FindDbName(db
, zSchema
);
776 if( piSize
) *piSize
= -1;
777 if( iDb
<0 ) return 0;
779 MemStore
*pStore
= p
->pStore
;
780 assert( pStore
->pMutex
==0 );
781 if( piSize
) *piSize
= pStore
->sz
;
782 if( mFlags
& SQLITE_SERIALIZE_NOCOPY
){
783 pOut
= pStore
->aData
;
785 pOut
= sqlite3_malloc64( pStore
->sz
);
786 if( pOut
) memcpy(pOut
, pStore
->aData
, pStore
->sz
);
790 pBt
= db
->aDb
[iDb
].pBt
;
791 if( pBt
==0 ) return 0;
792 szPage
= sqlite3BtreeGetPageSize(pBt
);
793 zSql
= sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema
);
794 rc
= zSql
? sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0) : SQLITE_NOMEM
;
797 rc
= sqlite3_step(pStmt
);
798 if( rc
!=SQLITE_ROW
){
801 sz
= sqlite3_column_int64(pStmt
, 0)*szPage
;
802 if( piSize
) *piSize
= sz
;
803 if( mFlags
& SQLITE_SERIALIZE_NOCOPY
){
806 pOut
= sqlite3_malloc64( sz
);
808 int nPage
= sqlite3_column_int(pStmt
, 0);
809 Pager
*pPager
= sqlite3BtreePager(pBt
);
811 for(pgno
=1; pgno
<=nPage
; pgno
++){
813 unsigned char *pTo
= pOut
+ szPage
*(sqlite3_int64
)(pgno
-1);
814 rc
= sqlite3PagerGet(pPager
, pgno
, (DbPage
**)&pPage
, 0);
816 memcpy(pTo
, sqlite3PagerGetData(pPage
), szPage
);
818 memset(pTo
, 0, szPage
);
820 sqlite3PagerUnref(pPage
);
825 sqlite3_finalize(pStmt
);
829 /* Convert zSchema to a MemDB and initialize its content.
831 int sqlite3_deserialize(
832 sqlite3
*db
, /* The database connection */
833 const char *zSchema
, /* Which DB to reopen with the deserialization */
834 unsigned char *pData
, /* The serialized database content */
835 sqlite3_int64 szDb
, /* Number bytes in the deserialization */
836 sqlite3_int64 szBuf
, /* Total size of buffer pData[] */
837 unsigned mFlags
/* Zero or more SQLITE_DESERIALIZE_* flags */
841 sqlite3_stmt
*pStmt
= 0;
845 #ifdef SQLITE_ENABLE_API_ARMOR
846 if( !sqlite3SafetyCheckOk(db
) ){
847 return SQLITE_MISUSE_BKPT
;
849 if( szDb
<0 ) return SQLITE_MISUSE_BKPT
;
850 if( szBuf
<0 ) return SQLITE_MISUSE_BKPT
;
853 sqlite3_mutex_enter(db
->mutex
);
854 if( zSchema
==0 ) zSchema
= db
->aDb
[0].zDbSName
;
855 iDb
= sqlite3FindDbName(db
, zSchema
);
857 if( iDb
<2 && iDb
!=0 ){
859 goto end_deserialize
;
861 zSql
= sqlite3_mprintf("ATTACH x AS %Q", zSchema
);
865 rc
= sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0);
868 if( rc
) goto end_deserialize
;
869 db
->init
.iDb
= (u8
)iDb
;
870 db
->init
.reopenMemdb
= 1;
871 rc
= sqlite3_step(pStmt
);
872 db
->init
.reopenMemdb
= 0;
873 if( rc
!=SQLITE_DONE
){
875 goto end_deserialize
;
877 p
= memdbFromDbSchema(db
, zSchema
);
881 MemStore
*pStore
= p
->pStore
;
882 pStore
->aData
= pData
;
885 pStore
->szAlloc
= szBuf
;
886 pStore
->szMax
= szBuf
;
887 if( pStore
->szMax
<sqlite3GlobalConfig
.mxMemdbSize
){
888 pStore
->szMax
= sqlite3GlobalConfig
.mxMemdbSize
;
890 pStore
->mFlags
= mFlags
;
895 sqlite3_finalize(pStmt
);
896 if( pData
&& (mFlags
& SQLITE_DESERIALIZE_FREEONCLOSE
)!=0 ){
899 sqlite3_mutex_leave(db
->mutex
);
904 ** Return true if the VFS is the memvfs.
906 int sqlite3IsMemdb(const sqlite3_vfs
*pVfs
){
907 return pVfs
==&memdb_vfs
;
911 ** This routine is called when the extension is loaded.
912 ** Register the new VFS.
914 int sqlite3MemdbInit(void){
915 sqlite3_vfs
*pLower
= sqlite3_vfs_find(0);
917 if( NEVER(pLower
==0) ) return SQLITE_ERROR
;
918 sz
= pLower
->szOsFile
;
919 memdb_vfs
.pAppData
= pLower
;
920 /* The following conditional can only be true when compiled for
921 ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
922 ** it in, to be safe, but it is marked as NO_TEST since there
923 ** is no way to reach it under most builds. */
924 if( sz
<sizeof(MemFile
) ) sz
= sizeof(MemFile
); /*NO_TEST*/
925 memdb_vfs
.szOsFile
= sz
;
926 return sqlite3_vfs_register(&memdb_vfs
, 0);
928 #endif /* SQLITE_OMIT_DESERIALIZE */