replace use of sqlite3StrICmp with public sqlite3_stricmp API
[sqlcipher.git] / src / memdb.c
blob4e5751f9313b71ad8e9a36af415e576586360322
1 /*
2 ** 2016-09-07
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 ******************************************************************************
13 ** This file implements an in-memory VFS. A database is held as a contiguous
14 ** block of memory.
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
40 ** mutexes.
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.
68 **
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 */
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 */
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.
97 static struct MemFS {
98 int nMemStore; /* Number of shared MemStore objects */
99 MemStore **apMemStore; /* Array of all shared MemStore objects */
100 } memdb_g;
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 = {
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 */
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 */
184 ** Enter/leave the mutex on a MemStore
186 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
187 static void memdbEnter(MemStore *p){
188 UNUSED_PARAMETER(p);
190 static void memdbLeave(MemStore *p){
191 UNUSED_PARAMETER(p);
193 #else
194 static void memdbEnter(MemStore *p){
195 sqlite3_mutex_enter(p->pMutex);
197 static void memdbLeave(MemStore *p){
198 sqlite3_mutex_leave(p->pMutex);
200 #endif
205 ** Close an memdb-file.
206 ** Free the underlying MemStore object when its refcount drops to zero
207 ** or less.
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;
227 break;
230 sqlite3_mutex_leave(pVfsMutex);
231 }else{
232 memdbEnter(p);
234 p->nRef--;
235 if( p->nRef<=0 ){
236 if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
237 sqlite3_free(p->aData);
239 memdbLeave(p);
240 sqlite3_mutex_free(p->pMutex);
241 sqlite3_free(p);
242 }else{
243 memdbLeave(p);
245 return SQLITE_OK;
249 ** Read data from an memdb-file.
251 static int memdbRead(
252 sqlite3_file *pFile,
253 void *zBuf,
254 int iAmt,
255 sqlite_int64 iOfst
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;
265 memcpy(zBuf, p->aData+iOfst, iAmt);
266 memdbLeave(p);
267 return SQLITE_OK;
271 ** Try to enlarge the memory allocation to hold at least sz bytes
273 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
274 unsigned char *pNew;
275 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
276 return SQLITE_FULL;
278 if( newSz>p->szMax ){
279 return SQLITE_FULL;
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;
291 ** Write data to an memdb-file.
293 static int memdbWrite(
294 sqlite3_file *pFile,
295 const void *z,
296 int iAmt,
297 sqlite_int64 iOfst
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;
307 if( iOfst+iAmt>p->sz ){
308 int rc;
309 if( iOfst+iAmt>p->szAlloc
310 && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
312 memdbLeave(p);
313 return rc;
315 if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
316 p->sz = iOfst+iAmt;
318 memcpy(p->aData+iOfst, z, iAmt);
319 memdbLeave(p);
320 return SQLITE_OK;
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;
332 int rc = SQLITE_OK;
333 memdbEnter(p);
334 if( NEVER(size>p->sz) ){
335 rc = SQLITE_FULL;
336 }else{
337 p->sz = size;
339 memdbLeave(p);
340 return rc;
344 ** Sync an memdb-file.
346 static int memdbSync(sqlite3_file *pFile, int flags){
347 UNUSED_PARAMETER(pFile);
348 UNUSED_PARAMETER(flags);
349 return SQLITE_OK;
353 ** Return the current file-size of an memdb-file.
355 static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
356 MemStore *p = ((MemFile*)pFile)->pStore;
357 memdbEnter(p);
358 *pSize = p->sz;
359 memdbLeave(p);
360 return SQLITE_OK;
364 ** Lock an memdb-file.
366 static int memdbLock(sqlite3_file *pFile, int eLock){
367 MemFile *pThis = (MemFile*)pFile;
368 MemStore *p = pThis->pStore;
369 int rc = SQLITE_OK;
370 if( eLock==pThis->eLock ) return SQLITE_OK;
371 memdbEnter(p);
372 if( eLock>SQLITE_LOCK_SHARED ){
373 if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
374 rc = SQLITE_READONLY;
375 }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
376 if( p->nWrLock ){
377 rc = SQLITE_BUSY;
378 }else{
379 p->nWrLock = 1;
382 }else if( eLock==SQLITE_LOCK_SHARED ){
383 if( pThis->eLock > SQLITE_LOCK_SHARED ){
384 assert( p->nWrLock==1 );
385 p->nWrLock = 0;
386 }else if( p->nWrLock ){
387 rc = SQLITE_BUSY;
388 }else{
389 p->nRdLock++;
391 }else{
392 assert( eLock==SQLITE_LOCK_NONE );
393 if( pThis->eLock>SQLITE_LOCK_SHARED ){
394 assert( p->nWrLock==1 );
395 p->nWrLock = 0;
397 assert( p->nRdLock>0 );
398 p->nRdLock--;
400 if( rc==SQLITE_OK ) pThis->eLock = eLock;
401 memdbLeave(p);
402 return rc;
405 #if 0
407 ** This interface is only used for crash recovery, which does not
408 ** occur on an in-memory database.
410 static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
411 *pResOut = 0;
412 return SQLITE_OK;
414 #endif
418 ** File control method. For custom operations on an memdb-file.
420 static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
421 MemStore *p = ((MemFile*)pFile)->pStore;
422 int rc = SQLITE_NOTFOUND;
423 memdbEnter(p);
424 if( op==SQLITE_FCNTL_VFSNAME ){
425 *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
426 rc = SQLITE_OK;
428 if( op==SQLITE_FCNTL_SIZE_LIMIT ){
429 sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
430 if( iLimit<p->sz ){
431 if( iLimit<0 ){
432 iLimit = p->szMax;
433 }else{
434 iLimit = p->sz;
437 p->szMax = iLimit;
438 *(sqlite3_int64*)pArg = iLimit;
439 rc = SQLITE_OK;
441 memdbLeave(p);
442 return rc;
445 #if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
447 ** Return the sector-size in bytes for an memdb-file.
449 static int memdbSectorSize(sqlite3_file *pFile){
450 return 1024;
452 #endif
455 ** Return the device characteristic flags supported by an memdb-file.
457 static int memdbDeviceCharacteristics(sqlite3_file *pFile){
458 UNUSED_PARAMETER(pFile);
459 return SQLITE_IOCAP_ATOMIC |
460 SQLITE_IOCAP_POWERSAFE_OVERWRITE |
461 SQLITE_IOCAP_SAFE_APPEND |
462 SQLITE_IOCAP_SEQUENTIAL;
465 /* Fetch a page of a memory-mapped file */
466 static int memdbFetch(
467 sqlite3_file *pFile,
468 sqlite3_int64 iOfst,
469 int iAmt,
470 void **pp
472 MemStore *p = ((MemFile*)pFile)->pStore;
473 memdbEnter(p);
474 if( iOfst+iAmt>p->sz ){
475 *pp = 0;
476 }else{
477 p->nMmap++;
478 *pp = (void*)(p->aData + iOfst);
480 memdbLeave(p);
481 return SQLITE_OK;
484 /* Release a memory-mapped page */
485 static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
486 MemStore *p = ((MemFile*)pFile)->pStore;
487 UNUSED_PARAMETER(iOfst);
488 UNUSED_PARAMETER(pPage);
489 memdbEnter(p);
490 p->nMmap--;
491 memdbLeave(p);
492 return SQLITE_OK;
496 ** Open an mem file handle.
498 static int memdbOpen(
499 sqlite3_vfs *pVfs,
500 const char *zName,
501 sqlite3_file *pFd,
502 int flags,
503 int *pOutFlags
505 MemFile *pFile = (MemFile*)pFd;
506 MemStore *p = 0;
507 int szName;
508 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
509 return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
511 memset(pFile, 0, sizeof(*p));
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;
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;
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;
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;
553 p->nRef = 1;
554 memdbEnter(p);
555 }else{
556 memdbEnter(p);
557 p->nRef++;
559 sqlite3_mutex_leave(pVfsMutex);
560 }else{
561 p = sqlite3Malloc( sizeof(*p) );
562 if( p==0 ){
563 return SQLITE_NOMEM;
565 memset(p, 0, sizeof(*p));
566 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
567 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
569 pFile->pStore = p;
570 assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
571 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
572 pFd->pMethods = &memdb_io_methods;
573 memdbLeave(p);
574 return SQLITE_OK;
577 #if 0 /* Only used to delete rollback journals, super-journals, and WAL
578 ** files, none of which exist in memdb. So this routine is never used */
580 ** Delete the file located at zPath. If the dirSync argument is true,
581 ** ensure the file-system modifications are synced to disk before
582 ** returning.
584 static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
585 return SQLITE_IOERR_DELETE;
587 #endif
590 ** Test for access permissions. Return true if the requested permission
591 ** is available, or false otherwise.
593 ** With memdb, no files ever exist on disk. So always return false.
595 static int memdbAccess(
596 sqlite3_vfs *pVfs,
597 const char *zPath,
598 int flags,
599 int *pResOut
601 UNUSED_PARAMETER(pVfs);
602 UNUSED_PARAMETER(zPath);
603 UNUSED_PARAMETER(flags);
604 *pResOut = 0;
605 return SQLITE_OK;
609 ** Populate buffer zOut with the full canonical pathname corresponding
610 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
611 ** of at least (INST_MAX_PATHNAME+1) bytes.
613 static int memdbFullPathname(
614 sqlite3_vfs *pVfs,
615 const char *zPath,
616 int nOut,
617 char *zOut
619 UNUSED_PARAMETER(pVfs);
620 sqlite3_snprintf(nOut, zOut, "%s", zPath);
621 return SQLITE_OK;
625 ** Open the dynamic library located at zPath and return a handle.
627 static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
628 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
632 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
633 ** utf-8 string describing the most recent error encountered associated
634 ** with dynamic libraries.
636 static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
637 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
641 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
643 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
644 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
648 ** Close the dynamic library handle pHandle.
650 static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
651 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
655 ** Populate the buffer pointed to by zBufOut with nByte bytes of
656 ** random data.
658 static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
659 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
663 ** Sleep for nMicro microseconds. Return the number of microseconds
664 ** actually slept.
666 static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
667 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
670 #if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
672 ** Return the current time as a Julian Day number in *pTimeOut.
674 static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
675 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
677 #endif
679 static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
680 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
682 static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
683 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
687 ** Translate a database connection pointer and schema name into a
688 ** MemFile pointer.
690 static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
691 MemFile *p = 0;
692 MemStore *pStore;
693 int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
694 if( rc ) return 0;
695 if( p->base.pMethods!=&memdb_io_methods ) return 0;
696 pStore = p->pStore;
697 memdbEnter(pStore);
698 if( pStore->zFName!=0 ) p = 0;
699 memdbLeave(pStore);
700 return p;
704 ** Return the serialization of a database
706 unsigned char *sqlite3_serialize(
707 sqlite3 *db, /* The database connection */
708 const char *zSchema, /* Which database within the connection */
709 sqlite3_int64 *piSize, /* Write size here, if not NULL */
710 unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
712 MemFile *p;
713 int iDb;
714 Btree *pBt;
715 sqlite3_int64 sz;
716 int szPage = 0;
717 sqlite3_stmt *pStmt = 0;
718 unsigned char *pOut;
719 char *zSql;
720 int rc;
722 #ifdef SQLITE_ENABLE_API_ARMOR
723 if( !sqlite3SafetyCheckOk(db) ){
724 (void)SQLITE_MISUSE_BKPT;
725 return 0;
727 #endif
729 if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
730 p = memdbFromDbSchema(db, zSchema);
731 iDb = sqlite3FindDbName(db, zSchema);
732 if( piSize ) *piSize = -1;
733 if( iDb<0 ) return 0;
734 if( p ){
735 MemStore *pStore = p->pStore;
736 assert( pStore->pMutex==0 );
737 if( piSize ) *piSize = pStore->sz;
738 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
739 pOut = pStore->aData;
740 }else{
741 pOut = sqlite3_malloc64( pStore->sz );
742 if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
744 return pOut;
746 pBt = db->aDb[iDb].pBt;
747 if( pBt==0 ) return 0;
748 szPage = sqlite3BtreeGetPageSize(pBt);
749 zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
750 rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
751 sqlite3_free(zSql);
752 if( rc ) return 0;
753 rc = sqlite3_step(pStmt);
754 if( rc!=SQLITE_ROW ){
755 pOut = 0;
756 }else{
757 sz = sqlite3_column_int64(pStmt, 0)*szPage;
758 if( piSize ) *piSize = sz;
759 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
760 pOut = 0;
761 }else{
762 pOut = sqlite3_malloc64( sz );
763 if( pOut ){
764 int nPage = sqlite3_column_int(pStmt, 0);
765 Pager *pPager = sqlite3BtreePager(pBt);
766 int pgno;
767 for(pgno=1; pgno<=nPage; pgno++){
768 DbPage *pPage = 0;
769 unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
770 rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
771 if( rc==SQLITE_OK ){
772 memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
773 }else{
774 memset(pTo, 0, szPage);
776 sqlite3PagerUnref(pPage);
781 sqlite3_finalize(pStmt);
782 return pOut;
785 /* Convert zSchema to a MemDB and initialize its content.
787 int sqlite3_deserialize(
788 sqlite3 *db, /* The database connection */
789 const char *zSchema, /* Which DB to reopen with the deserialization */
790 unsigned char *pData, /* The serialized database content */
791 sqlite3_int64 szDb, /* Number bytes in the deserialization */
792 sqlite3_int64 szBuf, /* Total size of buffer pData[] */
793 unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
795 MemFile *p;
796 char *zSql;
797 sqlite3_stmt *pStmt = 0;
798 int rc;
799 int iDb;
801 #ifdef SQLITE_ENABLE_API_ARMOR
802 if( !sqlite3SafetyCheckOk(db) ){
803 return SQLITE_MISUSE_BKPT;
805 if( szDb<0 ) return SQLITE_MISUSE_BKPT;
806 if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
807 #endif
809 sqlite3_mutex_enter(db->mutex);
810 if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
811 iDb = sqlite3FindDbName(db, zSchema);
812 if( iDb<0 ){
813 rc = SQLITE_ERROR;
814 goto end_deserialize;
816 zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
817 if( zSql==0 ){
818 rc = SQLITE_NOMEM;
819 }else{
820 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
821 sqlite3_free(zSql);
823 if( rc ) goto end_deserialize;
824 db->init.iDb = (u8)iDb;
825 db->init.reopenMemdb = 1;
826 rc = sqlite3_step(pStmt);
827 db->init.reopenMemdb = 0;
828 if( rc!=SQLITE_DONE ){
829 rc = SQLITE_ERROR;
830 goto end_deserialize;
832 p = memdbFromDbSchema(db, zSchema);
833 if( p==0 ){
834 rc = SQLITE_ERROR;
835 }else{
836 MemStore *pStore = p->pStore;
837 pStore->aData = pData;
838 pData = 0;
839 pStore->sz = szDb;
840 pStore->szAlloc = szBuf;
841 pStore->szMax = szBuf;
842 if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
843 pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
845 pStore->mFlags = mFlags;
846 rc = SQLITE_OK;
849 end_deserialize:
850 sqlite3_finalize(pStmt);
851 if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
852 sqlite3_free(pData);
854 sqlite3_mutex_leave(db->mutex);
855 return rc;
859 ** This routine is called when the extension is loaded.
860 ** Register the new VFS.
862 int sqlite3MemdbInit(void){
863 sqlite3_vfs *pLower = sqlite3_vfs_find(0);
864 unsigned int sz;
865 if( NEVER(pLower==0) ) return SQLITE_ERROR;
866 sz = pLower->szOsFile;
867 memdb_vfs.pAppData = pLower;
868 /* The following conditional can only be true when compiled for
869 ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
870 ** it in, to be safe, but it is marked as NO_TEST since there
871 ** is no way to reach it under most builds. */
872 if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
873 memdb_vfs.szOsFile = sz;
874 return sqlite3_vfs_register(&memdb_vfs, 0);
876 #endif /* SQLITE_OMIT_DESERIALIZE */