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