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