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 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
);
120 ** Methods for MemVfs
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
*);
136 static sqlite3_vfs memdb_vfs
= {
138 0, /* szOsFile (set when registered) */
139 1024, /* mxPathname */
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 */
161 static const sqlite3_io_methods memdb_io_methods
= {
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 */
179 memdbFetch
, /* xFetch */
180 memdbUnfetch
/* xUnfetch */
184 ** Enter/leave the mutex on a MemStore
186 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
187 static void memdbEnter(MemStore
*p
){
190 static void memdbLeave(MemStore
*p
){
194 static void memdbEnter(MemStore
*p
){
195 sqlite3_mutex_enter(p
->pMutex
);
197 static void memdbLeave(MemStore
*p
){
198 sqlite3_mutex_leave(p
->pMutex
);
205 ** Close an memdb-file.
206 ** Free the underlying MemStore object when its refcount drops to zero
209 static int memdbClose(sqlite3_file
*pFile
){
210 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
213 #ifndef SQLITE_MUTEX_OMIT
214 sqlite3_mutex
*pVfsMutex
= sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1
);
216 sqlite3_mutex_enter(pVfsMutex
);
217 for(i
=0; ALWAYS(i
<memdb_g
.nMemStore
); i
++){
218 if( memdb_g
.apMemStore
[i
]==p
){
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;
230 sqlite3_mutex_leave(pVfsMutex
);
236 if( p
->mFlags
& SQLITE_DESERIALIZE_FREEONCLOSE
){
237 sqlite3_free(p
->aData
);
240 sqlite3_mutex_free(p
->pMutex
);
249 ** Read data from an memdb-file.
251 static int memdbRead(
257 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
259 if( iOfst
+iAmt
>p
->sz
){
260 memset(zBuf
, 0, iAmt
);
261 if( iOfst
<p
->sz
) memcpy(zBuf
, p
->aData
+iOfst
, p
->sz
- iOfst
);
263 return SQLITE_IOERR_SHORT_READ
;
265 memcpy(zBuf
, p
->aData
+iOfst
, iAmt
);
271 ** Try to enlarge the memory allocation to hold at least sz bytes
273 static int memdbEnlarge(MemStore
*p
, sqlite3_int64 newSz
){
275 if( (p
->mFlags
& SQLITE_DESERIALIZE_RESIZEABLE
)==0 || NEVER(p
->nMmap
>0) ){
278 if( newSz
>p
->szMax
){
282 if( newSz
>p
->szMax
) newSz
= p
->szMax
;
283 pNew
= sqlite3Realloc(p
->aData
, newSz
);
284 if( pNew
==0 ) return SQLITE_IOERR_NOMEM
;
291 ** Write data to an memdb-file.
293 static int memdbWrite(
299 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
301 if( NEVER(p
->mFlags
& SQLITE_DESERIALIZE_READONLY
) ){
302 /* Can't happen: memdbLock() will return SQLITE_READONLY before
303 ** reaching this point */
305 return SQLITE_IOERR_WRITE
;
307 if( iOfst
+iAmt
>p
->sz
){
309 if( iOfst
+iAmt
>p
->szAlloc
310 && (rc
= memdbEnlarge(p
, iOfst
+iAmt
))!=SQLITE_OK
315 if( iOfst
>p
->sz
) memset(p
->aData
+p
->sz
, 0, iOfst
-p
->sz
);
318 memcpy(p
->aData
+iOfst
, z
, iAmt
);
324 ** Truncate an memdb-file.
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.
330 static int memdbTruncate(sqlite3_file
*pFile
, sqlite_int64 size
){
331 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
335 /* This can only happen with a corrupt wal mode db */
345 ** Sync an memdb-file.
347 static int memdbSync(sqlite3_file
*pFile
, int flags
){
348 UNUSED_PARAMETER(pFile
);
349 UNUSED_PARAMETER(flags
);
354 ** Return the current file-size of an memdb-file.
356 static int memdbFileSize(sqlite3_file
*pFile
, sqlite_int64
*pSize
){
357 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
365 ** Lock an memdb-file.
367 static int memdbLock(sqlite3_file
*pFile
, int eLock
){
368 MemFile
*pThis
= (MemFile
*)pFile
;
369 MemStore
*p
= pThis
->pStore
;
371 if( eLock
==pThis
->eLock
) return SQLITE_OK
;
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
){
383 }else if( eLock
==SQLITE_LOCK_SHARED
){
384 if( pThis
->eLock
> SQLITE_LOCK_SHARED
){
385 assert( p
->nWrLock
==1 );
387 }else if( p
->nWrLock
){
393 assert( eLock
==SQLITE_LOCK_NONE
);
394 if( pThis
->eLock
>SQLITE_LOCK_SHARED
){
395 assert( p
->nWrLock
==1 );
398 assert( p
->nRdLock
>0 );
401 if( rc
==SQLITE_OK
) pThis
->eLock
= eLock
;
408 ** This interface is only used for crash recovery, which does not
409 ** occur on an in-memory database.
411 static int memdbCheckReservedLock(sqlite3_file
*pFile
, int *pResOut
){
419 ** File control method. For custom operations on an memdb-file.
421 static int memdbFileControl(sqlite3_file
*pFile
, int op
, void *pArg
){
422 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
423 int rc
= SQLITE_NOTFOUND
;
425 if( op
==SQLITE_FCNTL_VFSNAME
){
426 *(char**)pArg
= sqlite3_mprintf("memdb(%p,%lld)", p
->aData
, p
->sz
);
429 if( op
==SQLITE_FCNTL_SIZE_LIMIT
){
430 sqlite3_int64 iLimit
= *(sqlite3_int64
*)pArg
;
439 *(sqlite3_int64
*)pArg
= iLimit
;
446 #if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
448 ** Return the sector-size in bytes for an memdb-file.
450 static int memdbSectorSize(sqlite3_file
*pFile
){
456 ** Return the device characteristic flags supported by an memdb-file.
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
;
466 /* Fetch a page of a memory-mapped file */
467 static int memdbFetch(
473 MemStore
*p
= ((MemFile
*)pFile
)->pStore
;
475 if( iOfst
+iAmt
>p
->sz
|| (p
->mFlags
& SQLITE_DESERIALIZE_RESIZEABLE
)!=0 ){
479 *pp
= (void*)(p
->aData
+ iOfst
);
485 /* Release a memory-mapped page */
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
);
497 ** Open an mem file handle.
499 static int memdbOpen(
506 MemFile
*pFile
= (MemFile
*)pFd
;
509 UNUSED_PARAMETER(pVfs
);
511 memset(pFile
, 0, sizeof(*pFile
));
512 szName
= sqlite3Strlen30(zName
);
513 if( szName
>1 && zName
[0]=='/' ){
515 #ifndef SQLITE_MUTEX_OMIT
516 sqlite3_mutex
*pVfsMutex
= sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1
);
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
];
527 p
= sqlite3Malloc( sizeof(*p
) + szName
+ 3 );
529 sqlite3_mutex_leave(pVfsMutex
);
532 apNew
= sqlite3Realloc(memdb_g
.apMemStore
,
533 sizeof(apNew
[0])*(memdb_g
.nMemStore
+1) );
536 sqlite3_mutex_leave(pVfsMutex
);
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
);
550 sqlite3_mutex_leave(pVfsMutex
);
559 sqlite3_mutex_leave(pVfsMutex
);
561 p
= sqlite3Malloc( sizeof(*p
) );
565 memset(p
, 0, sizeof(*p
));
566 p
->mFlags
= SQLITE_DESERIALIZE_RESIZEABLE
| SQLITE_DESERIALIZE_FREEONCLOSE
;
567 p
->szMax
= sqlite3GlobalConfig
.mxMemdbSize
;
571 *pOutFlags
= flags
| SQLITE_OPEN_MEMORY
;
573 pFd
->pMethods
= &memdb_io_methods
;
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 */
581 ** Delete the file located at zPath. If the dirSync argument is true,
582 ** ensure the file-system modifications are synced to disk before
585 static int memdbDelete(sqlite3_vfs
*pVfs
, const char *zPath
, int dirSync
){
586 return SQLITE_IOERR_DELETE
;
591 ** Test for access permissions. Return true if the requested permission
592 ** is available, or false otherwise.
594 ** With memdb, no files ever exist on disk. So always return false.
596 static int memdbAccess(
602 UNUSED_PARAMETER(pVfs
);
603 UNUSED_PARAMETER(zPath
);
604 UNUSED_PARAMETER(flags
);
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.
614 static int memdbFullPathname(
620 UNUSED_PARAMETER(pVfs
);
621 sqlite3_snprintf(nOut
, zOut
, "%s", zPath
);
626 ** Open the dynamic library located at zPath and return a handle.
628 static void *memdbDlOpen(sqlite3_vfs
*pVfs
, const char *zPath
){
629 return ORIGVFS(pVfs
)->xDlOpen(ORIGVFS(pVfs
), zPath
);
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.
637 static void memdbDlError(sqlite3_vfs
*pVfs
, int nByte
, char *zErrMsg
){
638 ORIGVFS(pVfs
)->xDlError(ORIGVFS(pVfs
), nByte
, zErrMsg
);
642 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
644 static void (*memdbDlSym(sqlite3_vfs
*pVfs
, void *p
, const char *zSym
))(void){
645 return ORIGVFS(pVfs
)->xDlSym(ORIGVFS(pVfs
), p
, zSym
);
649 ** Close the dynamic library handle pHandle.
651 static void memdbDlClose(sqlite3_vfs
*pVfs
, void *pHandle
){
652 ORIGVFS(pVfs
)->xDlClose(ORIGVFS(pVfs
), pHandle
);
656 ** Populate the buffer pointed to by zBufOut with nByte bytes of
659 static int memdbRandomness(sqlite3_vfs
*pVfs
, int nByte
, char *zBufOut
){
660 return ORIGVFS(pVfs
)->xRandomness(ORIGVFS(pVfs
), nByte
, zBufOut
);
664 ** Sleep for nMicro microseconds. Return the number of microseconds
667 static int memdbSleep(sqlite3_vfs
*pVfs
, int nMicro
){
668 return ORIGVFS(pVfs
)->xSleep(ORIGVFS(pVfs
), nMicro
);
671 #if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
673 ** Return the current time as a Julian Day number in *pTimeOut.
675 static int memdbCurrentTime(sqlite3_vfs
*pVfs
, double *pTimeOut
){
676 return ORIGVFS(pVfs
)->xCurrentTime(ORIGVFS(pVfs
), pTimeOut
);
680 static int memdbGetLastError(sqlite3_vfs
*pVfs
, int a
, char *b
){
681 return ORIGVFS(pVfs
)->xGetLastError(ORIGVFS(pVfs
), a
, b
);
683 static int memdbCurrentTimeInt64(sqlite3_vfs
*pVfs
, sqlite3_int64
*p
){
684 return ORIGVFS(pVfs
)->xCurrentTimeInt64(ORIGVFS(pVfs
), p
);
688 ** Translate a database connection pointer and schema name into a
691 static MemFile
*memdbFromDbSchema(sqlite3
*db
, const char *zSchema
){
694 int rc
= sqlite3_file_control(db
, zSchema
, SQLITE_FCNTL_FILE_POINTER
, &p
);
696 if( p
->base
.pMethods
!=&memdb_io_methods
) return 0;
699 if( pStore
->zFName
!=0 ) p
= 0;
705 ** Return the serialization of a database
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 */
718 sqlite3_stmt
*pStmt
= 0;
723 #ifdef SQLITE_ENABLE_API_ARMOR
724 if( !sqlite3SafetyCheckOk(db
) ){
725 (void)SQLITE_MISUSE_BKPT
;
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;
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
;
742 pOut
= sqlite3_malloc64( pStore
->sz
);
743 if( pOut
) memcpy(pOut
, pStore
->aData
, pStore
->sz
);
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
;
754 rc
= sqlite3_step(pStmt
);
755 if( rc
!=SQLITE_ROW
){
758 sz
= sqlite3_column_int64(pStmt
, 0)*szPage
;
759 if( piSize
) *piSize
= sz
;
760 if( mFlags
& SQLITE_SERIALIZE_NOCOPY
){
763 pOut
= sqlite3_malloc64( sz
);
765 int nPage
= sqlite3_column_int(pStmt
, 0);
766 Pager
*pPager
= sqlite3BtreePager(pBt
);
768 for(pgno
=1; pgno
<=nPage
; pgno
++){
770 unsigned char *pTo
= pOut
+ szPage
*(sqlite3_int64
)(pgno
-1);
771 rc
= sqlite3PagerGet(pPager
, pgno
, (DbPage
**)&pPage
, 0);
773 memcpy(pTo
, sqlite3PagerGetData(pPage
), szPage
);
775 memset(pTo
, 0, szPage
);
777 sqlite3PagerUnref(pPage
);
782 sqlite3_finalize(pStmt
);
786 /* Convert zSchema to a MemDB and initialize its content.
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 */
798 sqlite3_stmt
*pStmt
= 0;
802 #ifdef SQLITE_ENABLE_API_ARMOR
803 if( !sqlite3SafetyCheckOk(db
) ){
804 return SQLITE_MISUSE_BKPT
;
806 if( szDb
<0 ) return SQLITE_MISUSE_BKPT
;
807 if( szBuf
<0 ) return SQLITE_MISUSE_BKPT
;
810 sqlite3_mutex_enter(db
->mutex
);
811 if( zSchema
==0 ) zSchema
= db
->aDb
[0].zDbSName
;
812 iDb
= sqlite3FindDbName(db
, zSchema
);
814 if( iDb
<2 && iDb
!=0 ){
816 goto end_deserialize
;
818 zSql
= sqlite3_mprintf("ATTACH x AS %Q", zSchema
);
822 rc
= sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0);
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
){
832 goto end_deserialize
;
834 p
= memdbFromDbSchema(db
, zSchema
);
838 MemStore
*pStore
= p
->pStore
;
839 pStore
->aData
= pData
;
842 pStore
->szAlloc
= szBuf
;
843 pStore
->szMax
= szBuf
;
844 if( pStore
->szMax
<sqlite3GlobalConfig
.mxMemdbSize
){
845 pStore
->szMax
= sqlite3GlobalConfig
.mxMemdbSize
;
847 pStore
->mFlags
= mFlags
;
852 sqlite3_finalize(pStmt
);
853 if( pData
&& (mFlags
& SQLITE_DESERIALIZE_FREEONCLOSE
)!=0 ){
856 sqlite3_mutex_leave(db
->mutex
);
861 ** This routine is called when the extension is loaded.
862 ** Register the new VFS.
864 int sqlite3MemdbInit(void){
865 sqlite3_vfs
*pLower
= sqlite3_vfs_find(0);
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);
878 #endif /* SQLITE_OMIT_DESERIALIZE */