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 #ifdef SQLITE_ENABLE_DESERIALIZE 20 #include "sqliteInt.h" 21 22 /* 23 ** Forward declaration of objects used by this utility 24 */ 25 typedef struct sqlite3_vfs MemVfs; 26 typedef struct MemFile MemFile; 27 28 /* Access to a lower-level VFS that (might) implement dynamic loading, 29 ** access to randomness, etc. 30 */ 31 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) 32 33 /* An open file */ 34 struct MemFile { 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 */ 42 }; 43 44 /* 45 ** Methods for MemFile 46 */ 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); 60 61 /* 62 ** Methods for MemVfs 63 */ 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*); 77 78 static sqlite3_vfs memdb_vfs = { 79 2, /* iVersion */ 80 0, /* szOsFile (set when registered) */ 81 1024, /* mxPathname */ 82 0, /* pNext */ 83 "memdb", /* zName */ 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 */ 98 }; 99 100 static const sqlite3_io_methods memdb_io_methods = { 101 3, /* iVersion */ 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 */ 114 0, /* xShmMap */ 115 0, /* xShmLock */ 116 0, /* xShmBarrier */ 117 0, /* xShmUnmap */ 118 memdbFetch, /* xFetch */ 119 memdbUnfetch /* xUnfetch */ 120 }; 121 122 123 124 /* 125 ** Close an memdb-file. 126 ** 127 ** The pData pointer is owned by the application, so there is nothing 128 ** to free. 129 */ 130 static int memdbClose(sqlite3_file *pFile){ 131 MemFile *p = (MemFile *)pFile; 132 if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); 133 return SQLITE_OK; 134 } 135 136 /* 137 ** Read data from an memdb-file. 138 */ 139 static int memdbRead( 140 sqlite3_file *pFile, 141 void *zBuf, 142 int iAmt, 143 sqlite_int64 iOfst 144 ){ 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; 150 } 151 memcpy(zBuf, p->aData+iOfst, iAmt); 152 return SQLITE_OK; 153 } 154 155 /* 156 ** Try to enlarge the memory allocation to hold at least sz bytes 157 */ 158 static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ 159 unsigned char *pNew; 160 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ 161 return SQLITE_FULL; 162 } 163 pNew = sqlite3_realloc64(p->aData, newSz); 164 if( pNew==0 ) return SQLITE_NOMEM; 165 p->aData = pNew; 166 p->szMax = newSz; 167 return SQLITE_OK; 168 } 169 170 /* 171 ** Write data to an memdb-file. 172 */ 173 static int memdbWrite( 174 sqlite3_file *pFile, 175 const void *z, 176 int iAmt, 177 sqlite_int64 iOfst 178 ){ 179 MemFile *p = (MemFile *)pFile; 180 if( iOfst+iAmt>p->sz ){ 181 int rc; 182 if( iOfst+iAmt>p->szMax 183 && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK 184 ){ 185 return rc; 186 } 187 if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); 188 p->sz = iOfst+iAmt; 189 } 190 memcpy(p->aData+iOfst, z, iAmt); 191 return SQLITE_OK; 192 } 193 194 /* 195 ** Truncate an memdb-file. 196 ** 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. 200 */ 201 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ 202 MemFile *p = (MemFile *)pFile; 203 if( NEVER(size>p->sz) ) return SQLITE_FULL; 204 p->sz = size; 205 return SQLITE_OK; 206 } 207 208 /* 209 ** Sync an memdb-file. 210 */ 211 static int memdbSync(sqlite3_file *pFile, int flags){ 212 return SQLITE_OK; 213 } 214 215 /* 216 ** Return the current file-size of an memdb-file. 217 */ 218 static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 219 MemFile *p = (MemFile *)pFile; 220 *pSize = p->sz; 221 return SQLITE_OK; 222 } 223 224 /* 225 ** Lock an memdb-file. 226 */ 227 static int memdbLock(sqlite3_file *pFile, int eLock){ 228 MemFile *p = (MemFile *)pFile; 229 p->eLock = eLock; 230 return SQLITE_OK; 231 } 232 233 #if 0 /* Never used because memdbAccess() always returns false */ 234 /* 235 ** Check if another file-handle holds a RESERVED lock on an memdb-file. 236 */ 237 static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 238 *pResOut = 0; 239 return SQLITE_OK; 240 } 241 #endif 242 243 /* 244 ** File control method. For custom operations on an memdb-file. 245 */ 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); 251 rc = SQLITE_OK; 252 } 253 return rc; 254 } 255 256 #if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */ 257 /* 258 ** Return the sector-size in bytes for an memdb-file. 259 */ 260 static int memdbSectorSize(sqlite3_file *pFile){ 261 return 1024; 262 } 263 #endif 264 265 /* 266 ** Return the device characteristic flags supported by an memdb-file. 267 */ 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; 273 } 274 275 /* Fetch a page of a memory-mapped file */ 276 static int memdbFetch( 277 sqlite3_file *pFile, 278 sqlite3_int64 iOfst, 279 int iAmt, 280 void **pp 281 ){ 282 MemFile *p = (MemFile *)pFile; 283 p->nMmap++; 284 *pp = (void*)(p->aData + iOfst); 285 return SQLITE_OK; 286 } 287 288 /* Release a memory-mapped page */ 289 static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ 290 MemFile *p = (MemFile *)pFile; 291 p->nMmap--; 292 return SQLITE_OK; 293 } 294 295 /* 296 ** Open an mem file handle. 297 */ 298 static int memdbOpen( 299 sqlite3_vfs *pVfs, 300 const char *zName, 301 sqlite3_file *pFile, 302 int flags, 303 int *pOutFlags 304 ){ 305 MemFile *p = (MemFile*)pFile; 306 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ 307 return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags); 308 } 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; 314 return SQLITE_OK; 315 } 316 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 */ 319 /* 320 ** Delete the file located at zPath. If the dirSync argument is true, 321 ** ensure the file-system modifications are synced to disk before 322 ** returning. 323 */ 324 static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 325 return SQLITE_IOERR_DELETE; 326 } 327 #endif 328 329 /* 330 ** Test for access permissions. Return true if the requested permission 331 ** is available, or false otherwise. 332 ** 333 ** With memdb, no files ever exist on disk. So always return false. 334 */ 335 static int memdbAccess( 336 sqlite3_vfs *pVfs, 337 const char *zPath, 338 int flags, 339 int *pResOut 340 ){ 341 *pResOut = 0; 342 return SQLITE_OK; 343 } 344 345 /* 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. 349 */ 350 static int memdbFullPathname( 351 sqlite3_vfs *pVfs, 352 const char *zPath, 353 int nOut, 354 char *zOut 355 ){ 356 sqlite3_snprintf(nOut, zOut, "%s", zPath); 357 return SQLITE_OK; 358 } 359 360 /* 361 ** Open the dynamic library located at zPath and return a handle. 362 */ 363 static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 364 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); 365 } 366 367 /* 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. 371 */ 372 static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 373 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); 374 } 375 376 /* 377 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 378 */ 379 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ 380 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); 381 } 382 383 /* 384 ** Close the dynamic library handle pHandle. 385 */ 386 static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ 387 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); 388 } 389 390 /* 391 ** Populate the buffer pointed to by zBufOut with nByte bytes of 392 ** random data. 393 */ 394 static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 395 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); 396 } 397 398 /* 399 ** Sleep for nMicro microseconds. Return the number of microseconds 400 ** actually slept. 401 */ 402 static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ 403 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); 404 } 405 406 #if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */ 407 /* 408 ** Return the current time as a Julian Day number in *pTimeOut. 409 */ 410 static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 411 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); 412 } 413 #endif 414 415 static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ 416 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); 417 } 418 static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ 419 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); 420 } 421 422 /* 423 ** Translate a database connection pointer and schema name into a 424 ** MemFile pointer. 425 */ 426 static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ 427 MemFile *p = 0; 428 int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); 429 if( rc ) return 0; 430 if( p->base.pMethods!=&memdb_io_methods ) return 0; 431 return p; 432 } 433 434 /* 435 ** Return the serialization of a database 436 */ 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 */ 442 ){ 443 MemFile *p; 444 int iDb; 445 Btree *pBt; 446 sqlite3_int64 sz; 447 int szPage = 0; 448 sqlite3_stmt *pStmt = 0; 449 unsigned char *pOut; 450 char *zSql; 451 int rc; 452 453 #ifdef SQLITE_ENABLE_API_ARMOR 454 if( !sqlite3SafetyCheckOk(db) ){ 455 (void)SQLITE_MISUSE_BKPT; 456 return 0; 457 } 458 #endif 459 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; 465 if( p ){ 466 if( piSize ) *piSize = p->sz; 467 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ 468 pOut = p->aData; 469 }else{ 470 pOut = sqlite3_malloc64( p->sz ); 471 if( pOut ) memcpy(pOut, p->aData, p->sz); 472 } 473 return pOut; 474 } 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; 480 sqlite3_free(zSql); 481 if( rc ) return 0; 482 rc = sqlite3_step(pStmt); 483 if( rc!=SQLITE_ROW ){ 484 pOut = 0; 485 }else{ 486 sz = sqlite3_column_int64(pStmt, 0)*szPage; 487 if( piSize ) *piSize = sz; 488 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ 489 pOut = 0; 490 }else{ 491 pOut = sqlite3_malloc64( sz ); 492 if( pOut ){ 493 int nPage = sqlite3_column_int(pStmt, 0); 494 Pager *pPager = sqlite3BtreePager(pBt); 495 int pgno; 496 for(pgno=1; pgno<=nPage; pgno++){ 497 DbPage *pPage = 0; 498 unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); 499 rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); 500 if( rc==SQLITE_OK ){ 501 memcpy(pTo, sqlite3PagerGetData(pPage), szPage); 502 }else{ 503 memset(pTo, 0, szPage); 504 } 505 sqlite3PagerUnref(pPage); 506 } 507 } 508 } 509 } 510 sqlite3_finalize(pStmt); 511 return pOut; 512 } 513 514 /* Convert zSchema to a MemDB and initialize its content. 515 */ 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 */ 523 ){ 524 MemFile *p; 525 char *zSql; 526 sqlite3_stmt *pStmt = 0; 527 int rc; 528 int iDb; 529 530 #ifdef SQLITE_ENABLE_API_ARMOR 531 if( !sqlite3SafetyCheckOk(db) ){ 532 return SQLITE_MISUSE_BKPT; 533 } 534 if( szDb<0 ) return SQLITE_MISUSE_BKPT; 535 if( szBuf<0 ) return SQLITE_MISUSE_BKPT; 536 #endif 537 538 sqlite3_mutex_enter(db->mutex); 539 if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; 540 iDb = sqlite3FindDbName(db, zSchema); 541 if( iDb<0 ){ 542 rc = SQLITE_ERROR; 543 goto end_deserialize; 544 } 545 zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); 546 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); 547 sqlite3_free(zSql); 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 ){ 554 rc = SQLITE_ERROR; 555 goto end_deserialize; 556 } 557 p = memdbFromDbSchema(db, zSchema); 558 if( p==0 ){ 559 rc = SQLITE_ERROR; 560 }else{ 561 p->aData = pData; 562 p->sz = szDb; 563 p->szMax = szBuf; 564 p->mFlags = mFlags; 565 rc = SQLITE_OK; 566 } 567 568 end_deserialize: 569 sqlite3_finalize(pStmt); 570 sqlite3_mutex_leave(db->mutex); 571 return rc; 572 } 573 574 /* 575 ** This routine is called when the extension is loaded. 576 ** Register the new VFS. 577 */ 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); 588 } 589 #endif /* SQLITE_ENABLE_DESERIALIZE */ 590