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 is an in-memory VFS implementation. The application supplies 14 ** a chunk of memory to hold the database file. 15 ** 16 ** Because there is place to store a rollback or wal journal, the database 17 ** must use one of journal_mode=MEMORY or journal_mode=NONE. 18 ** 19 ** USAGE: 20 ** 21 ** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336&max=65536", &db, 22 ** SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI, 23 ** "memvfs"); 24 ** 25 ** These are the query parameters: 26 ** 27 ** ptr= The address of the memory buffer that holds the database. 28 ** 29 ** sz= The current size the database file 30 ** 31 ** maxsz= The maximum size of the database. In other words, the 32 ** amount of space allocated for the ptr= buffer. 33 ** 34 ** freeonclose= If true, then sqlite3_free() is called on the ptr= 35 ** value when the connection closes. 36 ** 37 ** The ptr= and sz= query parameters are required. If maxsz= is omitted, 38 ** then it defaults to the sz= value. Parameter values can be in either 39 ** decimal or hexadecimal. The filename in the URI is ignored. 40 */ 41 #include <sqlite3ext.h> 42 SQLITE_EXTENSION_INIT1 43 #include <string.h> 44 #include <assert.h> 45 46 47 /* 48 ** Forward declaration of objects used by this utility 49 */ 50 typedef struct sqlite3_vfs MemVfs; 51 typedef struct MemFile MemFile; 52 53 /* Access to a lower-level VFS that (might) implement dynamic loading, 54 ** access to randomness, etc. 55 */ 56 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) 57 58 /* An open file */ 59 struct MemFile { 60 sqlite3_file base; /* IO methods */ 61 sqlite3_int64 sz; /* Size of the file */ 62 sqlite3_int64 szMax; /* Space allocated to aData */ 63 unsigned char *aData; /* content of the file */ 64 int bFreeOnClose; /* Invoke sqlite3_free() on aData at close */ 65 }; 66 67 /* 68 ** Methods for MemFile 69 */ 70 static int memClose(sqlite3_file*); 71 static int memRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 72 static int memWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); 73 static int memTruncate(sqlite3_file*, sqlite3_int64 size); 74 static int memSync(sqlite3_file*, int flags); 75 static int memFileSize(sqlite3_file*, sqlite3_int64 *pSize); 76 static int memLock(sqlite3_file*, int); 77 static int memUnlock(sqlite3_file*, int); 78 static int memCheckReservedLock(sqlite3_file*, int *pResOut); 79 static int memFileControl(sqlite3_file*, int op, void *pArg); 80 static int memSectorSize(sqlite3_file*); 81 static int memDeviceCharacteristics(sqlite3_file*); 82 static int memShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); 83 static int memShmLock(sqlite3_file*, int offset, int n, int flags); 84 static void memShmBarrier(sqlite3_file*); 85 static int memShmUnmap(sqlite3_file*, int deleteFlag); 86 static int memFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); 87 static int memUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); 88 89 /* 90 ** Methods for MemVfs 91 */ 92 static int memOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); 93 static int memDelete(sqlite3_vfs*, const char *zName, int syncDir); 94 static int memAccess(sqlite3_vfs*, const char *zName, int flags, int *); 95 static int memFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); 96 static void *memDlOpen(sqlite3_vfs*, const char *zFilename); 97 static void memDlError(sqlite3_vfs*, int nByte, char *zErrMsg); 98 static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); 99 static void memDlClose(sqlite3_vfs*, void*); 100 static int memRandomness(sqlite3_vfs*, int nByte, char *zOut); 101 static int memSleep(sqlite3_vfs*, int microseconds); 102 static int memCurrentTime(sqlite3_vfs*, double*); 103 static int memGetLastError(sqlite3_vfs*, int, char *); 104 static int memCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); 105 106 static sqlite3_vfs mem_vfs = { 107 2, /* iVersion */ 108 0, /* szOsFile (set when registered) */ 109 1024, /* mxPathname */ 110 0, /* pNext */ 111 "memvfs", /* zName */ 112 0, /* pAppData (set when registered) */ 113 memOpen, /* xOpen */ 114 memDelete, /* xDelete */ 115 memAccess, /* xAccess */ 116 memFullPathname, /* xFullPathname */ 117 memDlOpen, /* xDlOpen */ 118 memDlError, /* xDlError */ 119 memDlSym, /* xDlSym */ 120 memDlClose, /* xDlClose */ 121 memRandomness, /* xRandomness */ 122 memSleep, /* xSleep */ 123 memCurrentTime, /* xCurrentTime */ 124 memGetLastError, /* xGetLastError */ 125 memCurrentTimeInt64 /* xCurrentTimeInt64 */ 126 }; 127 128 static const sqlite3_io_methods mem_io_methods = { 129 3, /* iVersion */ 130 memClose, /* xClose */ 131 memRead, /* xRead */ 132 memWrite, /* xWrite */ 133 memTruncate, /* xTruncate */ 134 memSync, /* xSync */ 135 memFileSize, /* xFileSize */ 136 memLock, /* xLock */ 137 memUnlock, /* xUnlock */ 138 memCheckReservedLock, /* xCheckReservedLock */ 139 memFileControl, /* xFileControl */ 140 memSectorSize, /* xSectorSize */ 141 memDeviceCharacteristics, /* xDeviceCharacteristics */ 142 memShmMap, /* xShmMap */ 143 memShmLock, /* xShmLock */ 144 memShmBarrier, /* xShmBarrier */ 145 memShmUnmap, /* xShmUnmap */ 146 memFetch, /* xFetch */ 147 memUnfetch /* xUnfetch */ 148 }; 149 150 151 152 /* 153 ** Close an mem-file. 154 ** 155 ** The pData pointer is owned by the application, so there is nothing 156 ** to free. 157 */ 158 static int memClose(sqlite3_file *pFile){ 159 MemFile *p = (MemFile *)pFile; 160 if( p->bFreeOnClose ) sqlite3_free(p->aData); 161 return SQLITE_OK; 162 } 163 164 /* 165 ** Read data from an mem-file. 166 */ 167 static int memRead( 168 sqlite3_file *pFile, 169 void *zBuf, 170 int iAmt, 171 sqlite_int64 iOfst 172 ){ 173 MemFile *p = (MemFile *)pFile; 174 memcpy(zBuf, p->aData+iOfst, iAmt); 175 return SQLITE_OK; 176 } 177 178 /* 179 ** Write data to an mem-file. 180 */ 181 static int memWrite( 182 sqlite3_file *pFile, 183 const void *z, 184 int iAmt, 185 sqlite_int64 iOfst 186 ){ 187 MemFile *p = (MemFile *)pFile; 188 if( iOfst+iAmt>p->sz ){ 189 if( iOfst+iAmt>p->szMax ) return SQLITE_FULL; 190 if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); 191 p->sz = iOfst+iAmt; 192 } 193 memcpy(p->aData+iOfst, z, iAmt); 194 return SQLITE_OK; 195 } 196 197 /* 198 ** Truncate an mem-file. 199 */ 200 static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){ 201 MemFile *p = (MemFile *)pFile; 202 if( size>p->sz ){ 203 if( size>p->szMax ) return SQLITE_FULL; 204 memset(p->aData+p->sz, 0, size-p->sz); 205 } 206 p->sz = size; 207 return SQLITE_OK; 208 } 209 210 /* 211 ** Sync an mem-file. 212 */ 213 static int memSync(sqlite3_file *pFile, int flags){ 214 return SQLITE_OK; 215 } 216 217 /* 218 ** Return the current file-size of an mem-file. 219 */ 220 static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 221 MemFile *p = (MemFile *)pFile; 222 *pSize = p->sz; 223 return SQLITE_OK; 224 } 225 226 /* 227 ** Lock an mem-file. 228 */ 229 static int memLock(sqlite3_file *pFile, int eLock){ 230 return SQLITE_OK; 231 } 232 233 /* 234 ** Unlock an mem-file. 235 */ 236 static int memUnlock(sqlite3_file *pFile, int eLock){ 237 return SQLITE_OK; 238 } 239 240 /* 241 ** Check if another file-handle holds a RESERVED lock on an mem-file. 242 */ 243 static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 244 *pResOut = 0; 245 return SQLITE_OK; 246 } 247 248 /* 249 ** File control method. For custom operations on an mem-file. 250 */ 251 static int memFileControl(sqlite3_file *pFile, int op, void *pArg){ 252 MemFile *p = (MemFile *)pFile; 253 int rc = SQLITE_NOTFOUND; 254 if( op==SQLITE_FCNTL_VFSNAME ){ 255 *(char**)pArg = sqlite3_mprintf("mem(%p,%lld)", p->aData, p->sz); 256 rc = SQLITE_OK; 257 } 258 return rc; 259 } 260 261 /* 262 ** Return the sector-size in bytes for an mem-file. 263 */ 264 static int memSectorSize(sqlite3_file *pFile){ 265 return 1024; 266 } 267 268 /* 269 ** Return the device characteristic flags supported by an mem-file. 270 */ 271 static int memDeviceCharacteristics(sqlite3_file *pFile){ 272 return SQLITE_IOCAP_ATOMIC | 273 SQLITE_IOCAP_POWERSAFE_OVERWRITE | 274 SQLITE_IOCAP_SAFE_APPEND | 275 SQLITE_IOCAP_SEQUENTIAL; 276 } 277 278 /* Create a shared memory file mapping */ 279 static int memShmMap( 280 sqlite3_file *pFile, 281 int iPg, 282 int pgsz, 283 int bExtend, 284 void volatile **pp 285 ){ 286 return SQLITE_IOERR_SHMMAP; 287 } 288 289 /* Perform locking on a shared-memory segment */ 290 static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){ 291 return SQLITE_IOERR_SHMLOCK; 292 } 293 294 /* Memory barrier operation on shared memory */ 295 static void memShmBarrier(sqlite3_file *pFile){ 296 return; 297 } 298 299 /* Unmap a shared memory segment */ 300 static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){ 301 return SQLITE_OK; 302 } 303 304 /* Fetch a page of a memory-mapped file */ 305 static int memFetch( 306 sqlite3_file *pFile, 307 sqlite3_int64 iOfst, 308 int iAmt, 309 void **pp 310 ){ 311 MemFile *p = (MemFile *)pFile; 312 *pp = (void*)(p->aData + iOfst); 313 return SQLITE_OK; 314 } 315 316 /* Release a memory-mapped page */ 317 static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ 318 return SQLITE_OK; 319 } 320 321 /* 322 ** Open an mem file handle. 323 */ 324 static int memOpen( 325 sqlite3_vfs *pVfs, 326 const char *zName, 327 sqlite3_file *pFile, 328 int flags, 329 int *pOutFlags 330 ){ 331 MemFile *p = (MemFile*)pFile; 332 memset(p, 0, sizeof(*p)); 333 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN; 334 p->aData = (unsigned char*)sqlite3_uri_int64(zName,"ptr",0); 335 if( p->aData==0 ) return SQLITE_CANTOPEN; 336 p->sz = sqlite3_uri_int64(zName,"sz",0); 337 if( p->sz<0 ) return SQLITE_CANTOPEN; 338 p->szMax = sqlite3_uri_int64(zName,"max",p->sz); 339 if( p->szMax<p->sz ) return SQLITE_CANTOPEN; 340 p->bFreeOnClose = sqlite3_uri_boolean(zName,"freeonclose",0); 341 pFile->pMethods = &mem_io_methods; 342 return SQLITE_OK; 343 } 344 345 /* 346 ** Delete the file located at zPath. If the dirSync argument is true, 347 ** ensure the file-system modifications are synced to disk before 348 ** returning. 349 */ 350 static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 351 return SQLITE_IOERR_DELETE; 352 } 353 354 /* 355 ** Test for access permissions. Return true if the requested permission 356 ** is available, or false otherwise. 357 */ 358 static int memAccess( 359 sqlite3_vfs *pVfs, 360 const char *zPath, 361 int flags, 362 int *pResOut 363 ){ 364 *pResOut = 0; 365 return SQLITE_OK; 366 } 367 368 /* 369 ** Populate buffer zOut with the full canonical pathname corresponding 370 ** to the pathname in zPath. zOut is guaranteed to point to a buffer 371 ** of at least (INST_MAX_PATHNAME+1) bytes. 372 */ 373 static int memFullPathname( 374 sqlite3_vfs *pVfs, 375 const char *zPath, 376 int nOut, 377 char *zOut 378 ){ 379 sqlite3_snprintf(nOut, zOut, "%s", zPath); 380 return SQLITE_OK; 381 } 382 383 /* 384 ** Open the dynamic library located at zPath and return a handle. 385 */ 386 static void *memDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 387 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); 388 } 389 390 /* 391 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable 392 ** utf-8 string describing the most recent error encountered associated 393 ** with dynamic libraries. 394 */ 395 static void memDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 396 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); 397 } 398 399 /* 400 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 401 */ 402 static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ 403 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); 404 } 405 406 /* 407 ** Close the dynamic library handle pHandle. 408 */ 409 static void memDlClose(sqlite3_vfs *pVfs, void *pHandle){ 410 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); 411 } 412 413 /* 414 ** Populate the buffer pointed to by zBufOut with nByte bytes of 415 ** random data. 416 */ 417 static int memRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 418 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); 419 } 420 421 /* 422 ** Sleep for nMicro microseconds. Return the number of microseconds 423 ** actually slept. 424 */ 425 static int memSleep(sqlite3_vfs *pVfs, int nMicro){ 426 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); 427 } 428 429 /* 430 ** Return the current time as a Julian Day number in *pTimeOut. 431 */ 432 static int memCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 433 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); 434 } 435 436 static int memGetLastError(sqlite3_vfs *pVfs, int a, char *b){ 437 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); 438 } 439 static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ 440 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); 441 } 442 443 #ifdef MEMVFS_TEST 444 /* 445 ** memvfs_from_file(FILENAME, MAXSIZE) 446 ** 447 ** This an SQL function used to help in testing the memvfs VFS. The 448 ** function reads the content of a file into memory and then returns 449 ** a URI that can be handed to ATTACH to attach the memory buffer as 450 ** a database. Example: 451 ** 452 ** ATTACH memvfs_from_file('test.db',1048576) AS inmem; 453 ** 454 ** The optional MAXSIZE argument gives the size of the memory allocation 455 ** used to hold the database. If omitted, it defaults to the size of the 456 ** file on disk. 457 */ 458 #include <stdio.h> 459 static void memvfsFromFileFunc( 460 sqlite3_context *context, 461 int argc, 462 sqlite3_value **argv 463 ){ 464 unsigned char *p; 465 sqlite3_int64 sz; 466 sqlite3_int64 szMax; 467 FILE *in; 468 const char *zFilename = (const char*)sqlite3_value_text(argv[0]); 469 char *zUri; 470 471 if( zFilename==0 ) return; 472 in = fopen(zFilename, "rb"); 473 if( in==0 ) return; 474 fseek(in, 0, SEEK_END); 475 szMax = sz = ftell(in); 476 rewind(in); 477 if( argc>=2 ){ 478 szMax = sqlite3_value_int64(argv[1]); 479 if( szMax<sz ) szMax = sz; 480 } 481 p = sqlite3_malloc64( szMax ); 482 if( p==0 ){ 483 fclose(in); 484 sqlite3_result_error_nomem(context); 485 return; 486 } 487 fread(p, sz, 1, in); 488 fclose(in); 489 zUri = sqlite3_mprintf( 490 "file:/mem?vfs=memvfs&ptr=%lld&sz=%lld&max=%lld&freeonclose=1", 491 (sqlite3_int64)p, sz, szMax); 492 sqlite3_result_text(context, zUri, -1, sqlite3_free); 493 } 494 #endif /* MEMVFS_TEST */ 495 496 #ifdef MEMVFS_TEST 497 /* 498 ** memvfs_to_file(SCHEMA, FILENAME) 499 ** 500 ** The schema identified by SCHEMA must be a memvfs database. Write 501 ** the content of this database into FILENAME. 502 */ 503 static void memvfsToFileFunc( 504 sqlite3_context *context, 505 int argc, 506 sqlite3_value **argv 507 ){ 508 MemFile *p = 0; 509 FILE *out; 510 int rc; 511 sqlite3 *db = sqlite3_context_db_handle(context); 512 sqlite3_vfs *pVfs = 0; 513 const char *zSchema = (const char*)sqlite3_value_text(argv[0]); 514 const char *zFilename = (const char*)sqlite3_value_text(argv[1]); 515 516 if( zFilename==0 ) return; 517 out = fopen(zFilename, "wb"); 518 if( out==0 ) return; 519 rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_VFS_POINTER, &pVfs); 520 if( rc || pVfs==0 ) return; 521 if( strcmp(pVfs->zName,"memvfs")!=0 ) return; 522 rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); 523 if( rc ) return; 524 fwrite(p->aData, 1, (size_t)p->sz, out); 525 fclose(out); 526 } 527 #endif /* MEMVFS_TEST */ 528 529 #ifdef MEMVFS_TEST 530 /* Called for each new database connection */ 531 static int memvfsRegister( 532 sqlite3 *db, 533 char **pzErrMsg, 534 const struct sqlite3_api_routines *pThunk 535 ){ 536 sqlite3_create_function(db, "memvfs_from_file", 1, SQLITE_UTF8, 0, 537 memvfsFromFileFunc, 0, 0); 538 sqlite3_create_function(db, "memvfs_from_file", 2, SQLITE_UTF8, 0, 539 memvfsFromFileFunc, 0, 0); 540 sqlite3_create_function(db, "memvfs_to_file", 2, SQLITE_UTF8, 0, 541 memvfsToFileFunc, 0, 0); 542 return SQLITE_OK; 543 } 544 #endif /* MEMVFS_TEST */ 545 546 547 #ifdef _WIN32 548 __declspec(dllexport) 549 #endif 550 /* 551 ** This routine is called when the extension is loaded. 552 ** Register the new VFS. 553 */ 554 int sqlite3_memvfs_init( 555 sqlite3 *db, 556 char **pzErrMsg, 557 const sqlite3_api_routines *pApi 558 ){ 559 int rc = SQLITE_OK; 560 SQLITE_EXTENSION_INIT2(pApi); 561 mem_vfs.pAppData = sqlite3_vfs_find(0); 562 if( mem_vfs.pAppData==0 ) return SQLITE_ERROR; 563 mem_vfs.szOsFile = sizeof(MemFile); 564 rc = sqlite3_vfs_register(&mem_vfs, 1); 565 #ifdef MEMVFS_TEST 566 if( rc==SQLITE_OK ){ 567 rc = sqlite3_auto_extension((void(*)(void))memvfsRegister); 568 } 569 if( rc==SQLITE_OK ){ 570 rc = memvfsRegister(db, pzErrMsg, pApi); 571 } 572 #endif 573 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; 574 return rc; 575 } 576