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 #ifdef SQLITE_ENABLE_DESERIALIZE
20 #include "sqliteInt.h"
23 ** Forward declaration of objects used by this utility
25 typedef struct sqlite3_vfs MemVfs
;
26 typedef struct MemFile MemFile
;
28 /* Access to a lower-level VFS that (might) implement dynamic loading,
29 ** access to randomness, etc.
31 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
35 sqlite3_file base
; /* IO methods */
36 sqlite3_int64 sz
; /* Size of the file */
37 sqlite3_int64 szMax
; /* Space allocated to aData */
38 unsigned char *aData
; /* content of the file */
39 int nMmap
; /* Number of memory mapped pages */
40 unsigned mFlags
; /* Flags */
41 int eLock
; /* Most recent lock against this file */
45 ** Methods for MemFile
47 static int memdbClose(sqlite3_file
*);
48 static int memdbRead(sqlite3_file
*, void*, int iAmt
, sqlite3_int64 iOfst
);
49 static int memdbWrite(sqlite3_file
*,const void*,int iAmt
, sqlite3_int64 iOfst
);
50 static int memdbTruncate(sqlite3_file
*, sqlite3_int64 size
);
51 static int memdbSync(sqlite3_file
*, int flags
);
52 static int memdbFileSize(sqlite3_file
*, sqlite3_int64
*pSize
);
53 static int memdbLock(sqlite3_file
*, int);
54 /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
55 static int memdbFileControl(sqlite3_file
*, int op
, void *pArg
);
56 /* static int memdbSectorSize(sqlite3_file*); // not used */
57 static int memdbDeviceCharacteristics(sqlite3_file
*);
58 static int memdbFetch(sqlite3_file
*, sqlite3_int64 iOfst
, int iAmt
, void **pp
);
59 static int memdbUnfetch(sqlite3_file
*, sqlite3_int64 iOfst
, void *p
);
64 static int memdbOpen(sqlite3_vfs
*, const char *, sqlite3_file
*, int , int *);
65 /* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
66 static int memdbAccess(sqlite3_vfs
*, const char *zName
, int flags
, int *);
67 static int memdbFullPathname(sqlite3_vfs
*, const char *zName
, int, char *zOut
);
68 static void *memdbDlOpen(sqlite3_vfs
*, const char *zFilename
);
69 static void memdbDlError(sqlite3_vfs
*, int nByte
, char *zErrMsg
);
70 static void (*memdbDlSym(sqlite3_vfs
*pVfs
, void *p
, const char*zSym
))(void);
71 static void memdbDlClose(sqlite3_vfs
*, void*);
72 static int memdbRandomness(sqlite3_vfs
*, int nByte
, char *zOut
);
73 static int memdbSleep(sqlite3_vfs
*, int microseconds
);
74 /* static int memdbCurrentTime(sqlite3_vfs*, double*); */
75 static int memdbGetLastError(sqlite3_vfs
*, int, char *);
76 static int memdbCurrentTimeInt64(sqlite3_vfs
*, sqlite3_int64
*);
78 static sqlite3_vfs memdb_vfs
= {
80 0, /* szOsFile (set when registered) */
81 1024, /* mxPathname */
84 0, /* pAppData (set when registered) */
85 memdbOpen
, /* xOpen */
86 0, /* memdbDelete, */ /* xDelete */
87 memdbAccess
, /* xAccess */
88 memdbFullPathname
, /* xFullPathname */
89 memdbDlOpen
, /* xDlOpen */
90 memdbDlError
, /* xDlError */
91 memdbDlSym
, /* xDlSym */
92 memdbDlClose
, /* xDlClose */
93 memdbRandomness
, /* xRandomness */
94 memdbSleep
, /* xSleep */
95 0, /* memdbCurrentTime, */ /* xCurrentTime */
96 memdbGetLastError
, /* xGetLastError */
97 memdbCurrentTimeInt64
/* xCurrentTimeInt64 */
100 static const sqlite3_io_methods memdb_io_methods
= {
102 memdbClose
, /* xClose */
103 memdbRead
, /* xRead */
104 memdbWrite
, /* xWrite */
105 memdbTruncate
, /* xTruncate */
106 memdbSync
, /* xSync */
107 memdbFileSize
, /* xFileSize */
108 memdbLock
, /* xLock */
109 memdbLock
, /* xUnlock - same as xLock in this case */
110 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
111 memdbFileControl
, /* xFileControl */
112 0, /* memdbSectorSize,*/ /* xSectorSize */
113 memdbDeviceCharacteristics
, /* xDeviceCharacteristics */
118 memdbFetch
, /* xFetch */
119 memdbUnfetch
/* xUnfetch */
125 ** Close an memdb-file.
127 ** The pData pointer is owned by the application, so there is nothing
130 static int memdbClose(sqlite3_file
*pFile
){
131 MemFile
*p
= (MemFile
*)pFile
;
132 if( p
->mFlags
& SQLITE_DESERIALIZE_FREEONCLOSE
) sqlite3_free(p
->aData
);
137 ** Read data from an memdb-file.
139 static int memdbRead(
145 MemFile
*p
= (MemFile
*)pFile
;
146 if( iOfst
+iAmt
>p
->sz
){
147 memset(zBuf
, 0, iAmt
);
148 if( iOfst
<p
->sz
) memcpy(zBuf
, p
->aData
+iOfst
, p
->sz
- iOfst
);
149 return SQLITE_IOERR_SHORT_READ
;
151 memcpy(zBuf
, p
->aData
+iOfst
, iAmt
);
156 ** Try to enlarge the memory allocation to hold at least sz bytes
158 static int memdbEnlarge(MemFile
*p
, sqlite3_int64 newSz
){
160 if( (p
->mFlags
& SQLITE_DESERIALIZE_RESIZEABLE
)==0 || p
->nMmap
>0 ){
163 pNew
= sqlite3_realloc64(p
->aData
, newSz
);
164 if( pNew
==0 ) return SQLITE_NOMEM
;
171 ** Write data to an memdb-file.
173 static int memdbWrite(
179 MemFile
*p
= (MemFile
*)pFile
;
180 if( iOfst
+iAmt
>p
->sz
){
182 if( iOfst
+iAmt
>p
->szMax
183 && (rc
= memdbEnlarge(p
, (iOfst
+iAmt
)*2))!=SQLITE_OK
187 if( iOfst
>p
->sz
) memset(p
->aData
+p
->sz
, 0, iOfst
-p
->sz
);
190 memcpy(p
->aData
+iOfst
, z
, iAmt
);
195 ** Truncate an memdb-file.
197 ** In rollback mode (which is always the case for memdb, as it does not
198 ** support WAL mode) the truncate() method is only used to reduce
199 ** the size of a file, never to increase the size.
201 static int memdbTruncate(sqlite3_file
*pFile
, sqlite_int64 size
){
202 MemFile
*p
= (MemFile
*)pFile
;
203 if( NEVER(size
>p
->sz
) ) return SQLITE_FULL
;
209 ** Sync an memdb-file.
211 static int memdbSync(sqlite3_file
*pFile
, int flags
){
216 ** Return the current file-size of an memdb-file.
218 static int memdbFileSize(sqlite3_file
*pFile
, sqlite_int64
*pSize
){
219 MemFile
*p
= (MemFile
*)pFile
;
225 ** Lock an memdb-file.
227 static int memdbLock(sqlite3_file
*pFile
, int eLock
){
228 MemFile
*p
= (MemFile
*)pFile
;
233 #if 0 /* Never used because memdbAccess() always returns false */
235 ** Check if another file-handle holds a RESERVED lock on an memdb-file.
237 static int memdbCheckReservedLock(sqlite3_file
*pFile
, int *pResOut
){
244 ** File control method. For custom operations on an memdb-file.
246 static int memdbFileControl(sqlite3_file
*pFile
, int op
, void *pArg
){
247 MemFile
*p
= (MemFile
*)pFile
;
248 int rc
= SQLITE_NOTFOUND
;
249 if( op
==SQLITE_FCNTL_VFSNAME
){
250 *(char**)pArg
= sqlite3_mprintf("memdb(%p,%lld)", p
->aData
, p
->sz
);
256 #if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
258 ** Return the sector-size in bytes for an memdb-file.
260 static int memdbSectorSize(sqlite3_file
*pFile
){
266 ** Return the device characteristic flags supported by an memdb-file.
268 static int memdbDeviceCharacteristics(sqlite3_file
*pFile
){
269 return SQLITE_IOCAP_ATOMIC
|
270 SQLITE_IOCAP_POWERSAFE_OVERWRITE
|
271 SQLITE_IOCAP_SAFE_APPEND
|
272 SQLITE_IOCAP_SEQUENTIAL
;
275 /* Fetch a page of a memory-mapped file */
276 static int memdbFetch(
282 MemFile
*p
= (MemFile
*)pFile
;
284 *pp
= (void*)(p
->aData
+ iOfst
);
288 /* Release a memory-mapped page */
289 static int memdbUnfetch(sqlite3_file
*pFile
, sqlite3_int64 iOfst
, void *pPage
){
290 MemFile
*p
= (MemFile
*)pFile
;
296 ** Open an mem file handle.
298 static int memdbOpen(
305 MemFile
*p
= (MemFile
*)pFile
;
306 if( (flags
& SQLITE_OPEN_MAIN_DB
)==0 ){
307 return ORIGVFS(pVfs
)->xOpen(ORIGVFS(pVfs
), zName
, pFile
, flags
, pOutFlags
);
309 memset(p
, 0, sizeof(*p
));
310 p
->mFlags
= SQLITE_DESERIALIZE_RESIZEABLE
| SQLITE_DESERIALIZE_FREEONCLOSE
;
311 assert( pOutFlags
!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
312 *pOutFlags
= flags
| SQLITE_OPEN_MEMORY
;
313 p
->base
.pMethods
= &memdb_io_methods
;
317 #if 0 /* Only used to delete rollback journals, master journals, and WAL
318 ** files, none of which exist in memdb. So this routine is never used */
320 ** Delete the file located at zPath. If the dirSync argument is true,
321 ** ensure the file-system modifications are synced to disk before
324 static int memdbDelete(sqlite3_vfs
*pVfs
, const char *zPath
, int dirSync
){
325 return SQLITE_IOERR_DELETE
;
330 ** Test for access permissions. Return true if the requested permission
331 ** is available, or false otherwise.
333 ** With memdb, no files ever exist on disk. So always return false.
335 static int memdbAccess(
346 ** Populate buffer zOut with the full canonical pathname corresponding
347 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
348 ** of at least (INST_MAX_PATHNAME+1) bytes.
350 static int memdbFullPathname(
356 sqlite3_snprintf(nOut
, zOut
, "%s", zPath
);
361 ** Open the dynamic library located at zPath and return a handle.
363 static void *memdbDlOpen(sqlite3_vfs
*pVfs
, const char *zPath
){
364 return ORIGVFS(pVfs
)->xDlOpen(ORIGVFS(pVfs
), zPath
);
368 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
369 ** utf-8 string describing the most recent error encountered associated
370 ** with dynamic libraries.
372 static void memdbDlError(sqlite3_vfs
*pVfs
, int nByte
, char *zErrMsg
){
373 ORIGVFS(pVfs
)->xDlError(ORIGVFS(pVfs
), nByte
, zErrMsg
);
377 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
379 static void (*memdbDlSym(sqlite3_vfs
*pVfs
, void *p
, const char *zSym
))(void){
380 return ORIGVFS(pVfs
)->xDlSym(ORIGVFS(pVfs
), p
, zSym
);
384 ** Close the dynamic library handle pHandle.
386 static void memdbDlClose(sqlite3_vfs
*pVfs
, void *pHandle
){
387 ORIGVFS(pVfs
)->xDlClose(ORIGVFS(pVfs
), pHandle
);
391 ** Populate the buffer pointed to by zBufOut with nByte bytes of
394 static int memdbRandomness(sqlite3_vfs
*pVfs
, int nByte
, char *zBufOut
){
395 return ORIGVFS(pVfs
)->xRandomness(ORIGVFS(pVfs
), nByte
, zBufOut
);
399 ** Sleep for nMicro microseconds. Return the number of microseconds
402 static int memdbSleep(sqlite3_vfs
*pVfs
, int nMicro
){
403 return ORIGVFS(pVfs
)->xSleep(ORIGVFS(pVfs
), nMicro
);
406 #if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
408 ** Return the current time as a Julian Day number in *pTimeOut.
410 static int memdbCurrentTime(sqlite3_vfs
*pVfs
, double *pTimeOut
){
411 return ORIGVFS(pVfs
)->xCurrentTime(ORIGVFS(pVfs
), pTimeOut
);
415 static int memdbGetLastError(sqlite3_vfs
*pVfs
, int a
, char *b
){
416 return ORIGVFS(pVfs
)->xGetLastError(ORIGVFS(pVfs
), a
, b
);
418 static int memdbCurrentTimeInt64(sqlite3_vfs
*pVfs
, sqlite3_int64
*p
){
419 return ORIGVFS(pVfs
)->xCurrentTimeInt64(ORIGVFS(pVfs
), p
);
423 ** Translate a database connection pointer and schema name into a
426 static MemFile
*memdbFromDbSchema(sqlite3
*db
, const char *zSchema
){
428 int rc
= sqlite3_file_control(db
, zSchema
, SQLITE_FCNTL_FILE_POINTER
, &p
);
430 if( p
->base
.pMethods
!=&memdb_io_methods
) return 0;
435 ** Return the serialization of a database
437 unsigned char *sqlite3_serialize(
438 sqlite3
*db
, /* The database connection */
439 const char *zSchema
, /* Which database within the connection */
440 sqlite3_int64
*piSize
, /* Write size here, if not NULL */
441 unsigned int mFlags
/* Maybe SQLITE_SERIALIZE_NOCOPY */
448 sqlite3_stmt
*pStmt
= 0;
453 #ifdef SQLITE_ENABLE_API_ARMOR
454 if( !sqlite3SafetyCheckOk(db
) ){
455 (void)SQLITE_MISUSE_BKPT
;
460 if( zSchema
==0 ) zSchema
= db
->aDb
[0].zDbSName
;
461 p
= memdbFromDbSchema(db
, zSchema
);
462 iDb
= sqlite3FindDbName(db
, zSchema
);
463 if( piSize
) *piSize
= -1;
464 if( iDb
<0 ) return 0;
466 if( piSize
) *piSize
= p
->sz
;
467 if( mFlags
& SQLITE_SERIALIZE_NOCOPY
){
470 pOut
= sqlite3_malloc64( p
->sz
);
471 if( pOut
) memcpy(pOut
, p
->aData
, p
->sz
);
475 pBt
= db
->aDb
[iDb
].pBt
;
476 if( pBt
==0 ) return 0;
477 szPage
= sqlite3BtreeGetPageSize(pBt
);
478 zSql
= sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema
);
479 rc
= zSql
? sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0) : SQLITE_NOMEM
;
482 rc
= sqlite3_step(pStmt
);
483 if( rc
!=SQLITE_ROW
){
486 sz
= sqlite3_column_int64(pStmt
, 0)*szPage
;
487 if( piSize
) *piSize
= sz
;
488 if( mFlags
& SQLITE_SERIALIZE_NOCOPY
){
491 pOut
= sqlite3_malloc64( sz
);
493 int nPage
= sqlite3_column_int(pStmt
, 0);
494 Pager
*pPager
= sqlite3BtreePager(pBt
);
496 for(pgno
=1; pgno
<=nPage
; pgno
++){
498 unsigned char *pTo
= pOut
+ szPage
*(sqlite3_int64
)(pgno
-1);
499 rc
= sqlite3PagerGet(pPager
, pgno
, (DbPage
**)&pPage
, 0);
501 memcpy(pTo
, sqlite3PagerGetData(pPage
), szPage
);
503 memset(pTo
, 0, szPage
);
505 sqlite3PagerUnref(pPage
);
510 sqlite3_finalize(pStmt
);
514 /* Convert zSchema to a MemDB and initialize its content.
516 int sqlite3_deserialize(
517 sqlite3
*db
, /* The database connection */
518 const char *zSchema
, /* Which DB to reopen with the deserialization */
519 unsigned char *pData
, /* The serialized database content */
520 sqlite3_int64 szDb
, /* Number bytes in the deserialization */
521 sqlite3_int64 szBuf
, /* Total size of buffer pData[] */
522 unsigned mFlags
/* Zero or more SQLITE_DESERIALIZE_* flags */
526 sqlite3_stmt
*pStmt
= 0;
530 #ifdef SQLITE_ENABLE_API_ARMOR
531 if( !sqlite3SafetyCheckOk(db
) ){
532 return SQLITE_MISUSE_BKPT
;
534 if( szDb
<0 ) return SQLITE_MISUSE_BKPT
;
535 if( szBuf
<0 ) return SQLITE_MISUSE_BKPT
;
538 sqlite3_mutex_enter(db
->mutex
);
539 if( zSchema
==0 ) zSchema
= db
->aDb
[0].zDbSName
;
540 iDb
= sqlite3FindDbName(db
, zSchema
);
543 goto end_deserialize
;
545 zSql
= sqlite3_mprintf("ATTACH x AS %Q", zSchema
);
546 rc
= sqlite3_prepare_v2(db
, zSql
, -1, &pStmt
, 0);
548 if( rc
) goto end_deserialize
;
549 db
->init
.iDb
= (u8
)iDb
;
550 db
->init
.reopenMemdb
= 1;
551 rc
= sqlite3_step(pStmt
);
552 db
->init
.reopenMemdb
= 0;
553 if( rc
!=SQLITE_DONE
){
555 goto end_deserialize
;
557 p
= memdbFromDbSchema(db
, zSchema
);
569 sqlite3_finalize(pStmt
);
570 sqlite3_mutex_leave(db
->mutex
);
575 ** This routine is called when the extension is loaded.
576 ** Register the new VFS.
578 int sqlite3MemdbInit(void){
579 sqlite3_vfs
*pLower
= sqlite3_vfs_find(0);
580 int sz
= pLower
->szOsFile
;
581 memdb_vfs
.pAppData
= pLower
;
582 /* In all known configurations of SQLite, the size of a default
583 ** sqlite3_file is greater than the size of a memdb sqlite3_file.
584 ** Should that ever change, remove the following NEVER() */
585 if( NEVER(sz
<sizeof(MemFile
)) ) sz
= sizeof(MemFile
);
586 memdb_vfs
.szOsFile
= sz
;
587 return sqlite3_vfs_register(&memdb_vfs
, 0);
589 #endif /* SQLITE_ENABLE_DESERIALIZE */