OLD | NEW |
1 /* | 1 /* |
2 ** 2004 May 22 | 2 ** 2004 May 22 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 ** | 80 ** |
81 ** Device Characteristic flag handling: | 81 ** Device Characteristic flag handling: |
82 ** | 82 ** |
83 ** If the IOCAP_ATOMIC flag is set, then option (3) above is | 83 ** If the IOCAP_ATOMIC flag is set, then option (3) above is |
84 ** never selected. | 84 ** never selected. |
85 ** | 85 ** |
86 ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents | 86 ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents |
87 ** an aligned write() of an integer number of 512 byte regions, then | 87 ** an aligned write() of an integer number of 512 byte regions, then |
88 ** option (3) above is never selected. Instead, each 512 byte region | 88 ** option (3) above is never selected. Instead, each 512 byte region |
89 ** is either correctly written or left completely untouched. Similar | 89 ** is either correctly written or left completely untouched. Similar |
90 ** logic governs the behaviour if any of the other ATOMICXXX flags | 90 ** logic governs the behavior if any of the other ATOMICXXX flags |
91 ** is set. | 91 ** is set. |
92 ** | 92 ** |
93 ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set | 93 ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set |
94 ** and a crash is being simulated, then an entry of the write-list is | 94 ** and a crash is being simulated, then an entry of the write-list is |
95 ** selected at random. Everything in the list after the selected entry | 95 ** selected at random. Everything in the list after the selected entry |
96 ** is discarded before processing begins. | 96 ** is discarded before processing begins. |
97 ** | 97 ** |
98 ** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option | 98 ** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option |
99 ** (1) is selected for all write-list entries except the last. If a | 99 ** (1) is selected for all write-list entries except the last. If a |
100 ** crash is not being simulated, then all entries in the write-list | 100 ** crash is not being simulated, then all entries in the write-list |
(...skipping 25 matching lines...) Expand all Loading... |
126 struct CrashFile { | 126 struct CrashFile { |
127 const sqlite3_io_methods *pMethod; /* Must be first */ | 127 const sqlite3_io_methods *pMethod; /* Must be first */ |
128 sqlite3_file *pRealFile; /* Underlying "real" file handle */ | 128 sqlite3_file *pRealFile; /* Underlying "real" file handle */ |
129 char *zName; | 129 char *zName; |
130 int flags; /* Flags the file was opened with */ | 130 int flags; /* Flags the file was opened with */ |
131 | 131 |
132 /* Cache of the entire file. This is used to speed up OsRead() and | 132 /* Cache of the entire file. This is used to speed up OsRead() and |
133 ** OsFileSize() calls. Although both could be done by traversing the | 133 ** OsFileSize() calls. Although both could be done by traversing the |
134 ** write-list, in practice this is impractically slow. | 134 ** write-list, in practice this is impractically slow. |
135 */ | 135 */ |
136 int iSize; /* Size of file in bytes */ | 136 u8 *zData; /* Buffer containing file contents */ |
137 int nData; /* Size of buffer allocated at zData */ | 137 int nData; /* Size of buffer allocated at zData */ |
138 u8 *zData; /* Buffer containing file contents */ | 138 i64 iSize; /* Size of file in bytes */ |
139 }; | 139 }; |
140 | 140 |
141 struct CrashGlobal { | 141 struct CrashGlobal { |
142 WriteBuffer *pWriteList; /* Head of write-list */ | 142 WriteBuffer *pWriteList; /* Head of write-list */ |
143 WriteBuffer *pWriteListEnd; /* End of write-list */ | 143 WriteBuffer *pWriteListEnd; /* End of write-list */ |
144 | 144 |
145 int iSectorSize; /* Value of simulated sector size */ | 145 int iSectorSize; /* Value of simulated sector size */ |
146 int iDeviceCharacteristics; /* Value of simulated device characteristics */ | 146 int iDeviceCharacteristics; /* Value of simulated device characteristics */ |
147 | 147 |
148 int iCrash; /* Crash on the iCrash'th call to xSync() */ | 148 int iCrash; /* Crash on the iCrash'th call to xSync() */ |
(...skipping 17 matching lines...) Expand all Loading... |
166 return (void *)Tcl_Realloc(p, (size_t)n); | 166 return (void *)Tcl_Realloc(p, (size_t)n); |
167 } | 167 } |
168 | 168 |
169 /* | 169 /* |
170 ** Wrapper around the sqlite3OsWrite() function that avoids writing to the | 170 ** Wrapper around the sqlite3OsWrite() function that avoids writing to the |
171 ** 512 byte block begining at offset PENDING_BYTE. | 171 ** 512 byte block begining at offset PENDING_BYTE. |
172 */ | 172 */ |
173 static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ | 173 static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ |
174 int rc = SQLITE_OK; | 174 int rc = SQLITE_OK; |
175 int iSkip = 0; | 175 int iSkip = 0; |
176 if( iOff==PENDING_BYTE && (p->flags&SQLITE_OPEN_MAIN_DB) ){ | |
177 iSkip = 512; | |
178 } | |
179 if( (iAmt-iSkip)>0 ){ | 176 if( (iAmt-iSkip)>0 ){ |
180 rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], iAmt-iSkip, iOff+iSkip); | 177 rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], (int)(iAmt-iSkip), iOff+iSkip); |
181 } | 178 } |
182 return rc; | 179 return rc; |
183 } | 180 } |
184 | 181 |
185 /* | 182 /* |
186 ** Flush the write-list as if xSync() had been called on file handle | 183 ** Flush the write-list as if xSync() had been called on file handle |
187 ** pFile. If isCrash is true, simulate a crash. | 184 ** pFile. If isCrash is true, simulate a crash. |
188 */ | 185 */ |
189 static int writeListSync(CrashFile *pFile, int isCrash){ | 186 static int writeListSync(CrashFile *pFile, int isCrash){ |
190 int rc = SQLITE_OK; | 187 int rc = SQLITE_OK; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 if( isCrash ){ | 296 if( isCrash ){ |
300 printf("Omiting %d bytes @ %d (%s)\n", | 297 printf("Omiting %d bytes @ %d (%s)\n", |
301 pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName | 298 pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName |
302 ); | 299 ); |
303 } | 300 } |
304 #endif | 301 #endif |
305 break; | 302 break; |
306 } | 303 } |
307 case 3: { /* Trash sectors */ | 304 case 3: { /* Trash sectors */ |
308 u8 *zGarbage; | 305 u8 *zGarbage; |
309 int iFirst = (pWrite->iOffset/g.iSectorSize); | 306 int iFirst = (int)(pWrite->iOffset/g.iSectorSize); |
310 int iLast = (pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize; | 307 int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize); |
311 | 308 |
312 assert(pWrite->zBuf); | 309 assert(pWrite->zBuf); |
313 | 310 |
314 #ifdef TRACE_CRASHTEST | 311 #ifdef TRACE_CRASHTEST |
315 printf("Trashing %d sectors @ sector %d (%s)\n", | 312 printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", |
316 1+iLast-iFirst, iFirst, pWrite->pFile->zName | 313 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName |
317 ); | 314 ); |
318 #endif | 315 #endif |
319 | 316 |
320 zGarbage = crash_malloc(g.iSectorSize); | 317 zGarbage = crash_malloc(g.iSectorSize); |
321 if( zGarbage ){ | 318 if( zGarbage ){ |
322 sqlite3_int64 i; | 319 sqlite3_int64 i; |
323 for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ | 320 for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ |
324 sqlite3_randomness(g.iSectorSize, zGarbage); | 321 sqlite3_randomness(g.iSectorSize, zGarbage); |
325 rc = writeDbFile( | 322 rc = writeDbFile( |
326 pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize | 323 pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 /* | 399 /* |
403 ** Read data from a crash-file. | 400 ** Read data from a crash-file. |
404 */ | 401 */ |
405 static int cfRead( | 402 static int cfRead( |
406 sqlite3_file *pFile, | 403 sqlite3_file *pFile, |
407 void *zBuf, | 404 void *zBuf, |
408 int iAmt, | 405 int iAmt, |
409 sqlite_int64 iOfst | 406 sqlite_int64 iOfst |
410 ){ | 407 ){ |
411 CrashFile *pCrash = (CrashFile *)pFile; | 408 CrashFile *pCrash = (CrashFile *)pFile; |
| 409 int nCopy = (int)MIN((i64)iAmt, (pCrash->iSize - iOfst)); |
| 410 |
| 411 if( nCopy>0 ){ |
| 412 memcpy(zBuf, &pCrash->zData[iOfst], nCopy); |
| 413 } |
412 | 414 |
413 /* Check the file-size to see if this is a short-read */ | 415 /* Check the file-size to see if this is a short-read */ |
414 if( pCrash->iSize<(iOfst+iAmt) ){ | 416 if( nCopy<iAmt ){ |
415 return SQLITE_IOERR_SHORT_READ; | 417 return SQLITE_IOERR_SHORT_READ; |
416 } | 418 } |
417 | 419 |
418 memcpy(zBuf, &pCrash->zData[iOfst], iAmt); | |
419 return SQLITE_OK; | 420 return SQLITE_OK; |
420 } | 421 } |
421 | 422 |
422 /* | 423 /* |
423 ** Write data to a crash-file. | 424 ** Write data to a crash-file. |
424 */ | 425 */ |
425 static int cfWrite( | 426 static int cfWrite( |
426 sqlite3_file *pFile, | 427 sqlite3_file *pFile, |
427 const void *zBuf, | 428 const void *zBuf, |
428 int iAmt, | 429 int iAmt, |
429 sqlite_int64 iOfst | 430 sqlite_int64 iOfst |
430 ){ | 431 ){ |
431 CrashFile *pCrash = (CrashFile *)pFile; | 432 CrashFile *pCrash = (CrashFile *)pFile; |
432 if( iAmt+iOfst>pCrash->iSize ){ | 433 if( iAmt+iOfst>pCrash->iSize ){ |
433 pCrash->iSize = iAmt+iOfst; | 434 pCrash->iSize = (int)(iAmt+iOfst); |
434 } | 435 } |
435 while( pCrash->iSize>pCrash->nData ){ | 436 while( pCrash->iSize>pCrash->nData ){ |
436 u8 *zNew; | 437 u8 *zNew; |
437 int nNew = (pCrash->nData*2) + 4096; | 438 int nNew = (pCrash->nData*2) + 4096; |
438 zNew = crash_realloc(pCrash->zData, nNew); | 439 zNew = crash_realloc(pCrash->zData, nNew); |
439 if( !zNew ){ | 440 if( !zNew ){ |
440 return SQLITE_NOMEM; | 441 return SQLITE_NOMEM; |
441 } | 442 } |
442 memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData); | 443 memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData); |
443 pCrash->nData = nNew; | 444 pCrash->nData = nNew; |
444 pCrash->zData = zNew; | 445 pCrash->zData = zNew; |
445 } | 446 } |
446 memcpy(&pCrash->zData[iOfst], zBuf, iAmt); | 447 memcpy(&pCrash->zData[iOfst], zBuf, iAmt); |
447 return writeListAppend(pFile, iOfst, zBuf, iAmt); | 448 return writeListAppend(pFile, iOfst, zBuf, iAmt); |
448 } | 449 } |
449 | 450 |
450 /* | 451 /* |
451 ** Truncate a crash-file. | 452 ** Truncate a crash-file. |
452 */ | 453 */ |
453 static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){ | 454 static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){ |
454 CrashFile *pCrash = (CrashFile *)pFile; | 455 CrashFile *pCrash = (CrashFile *)pFile; |
455 assert(size>=0); | 456 assert(size>=0); |
456 if( pCrash->iSize>size ){ | 457 if( pCrash->iSize>size ){ |
457 pCrash->iSize = size; | 458 pCrash->iSize = (int)size; |
458 } | 459 } |
459 return writeListAppend(pFile, size, 0, 0); | 460 return writeListAppend(pFile, size, 0, 0); |
460 } | 461 } |
461 | 462 |
462 /* | 463 /* |
463 ** Sync a crash-file. | 464 ** Sync a crash-file. |
464 */ | 465 */ |
465 static int cfSync(sqlite3_file *pFile, int flags){ | 466 static int cfSync(sqlite3_file *pFile, int flags){ |
466 CrashFile *pCrash = (CrashFile *)pFile; | 467 CrashFile *pCrash = (CrashFile *)pFile; |
467 int isCrash = 0; | 468 int isCrash = 0; |
468 | 469 |
469 const char *zName = pCrash->zName; | 470 const char *zName = pCrash->zName; |
470 const char *zCrashFile = g.zCrashFile; | 471 const char *zCrashFile = g.zCrashFile; |
471 int nName = strlen(zName); | 472 int nName = (int)strlen(zName); |
472 int nCrashFile = strlen(zCrashFile); | 473 int nCrashFile = (int)strlen(zCrashFile); |
473 | 474 |
474 if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){ | 475 if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){ |
475 nCrashFile--; | 476 nCrashFile--; |
476 if( nName>nCrashFile ) nName = nCrashFile; | 477 if( nName>nCrashFile ) nName = nCrashFile; |
477 } | 478 } |
478 | 479 |
| 480 #ifdef TRACE_CRASHTEST |
| 481 printf("cfSync(): nName = %d, nCrashFile = %d, zName = %s, zCrashFile = %s\n", |
| 482 nName, nCrashFile, zName, zCrashFile); |
| 483 #endif |
| 484 |
479 if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){ | 485 if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){ |
| 486 #ifdef TRACE_CRASHTEST |
| 487 printf("cfSync(): name matched, g.iCrash = %d\n", g.iCrash); |
| 488 #endif |
480 if( (--g.iCrash)==0 ) isCrash = 1; | 489 if( (--g.iCrash)==0 ) isCrash = 1; |
481 } | 490 } |
482 | 491 |
483 return writeListSync(pCrash, isCrash); | 492 return writeListSync(pCrash, isCrash); |
484 } | 493 } |
485 | 494 |
486 /* | 495 /* |
487 ** Return the current file-size of the crash-file. | 496 ** Return the current file-size of the crash-file. |
488 */ | 497 */ |
489 static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ | 498 static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ |
490 CrashFile *pCrash = (CrashFile *)pFile; | 499 CrashFile *pCrash = (CrashFile *)pFile; |
491 *pSize = (i64)pCrash->iSize; | 500 *pSize = (i64)pCrash->iSize; |
492 return SQLITE_OK; | 501 return SQLITE_OK; |
493 } | 502 } |
494 | 503 |
495 /* | 504 /* |
496 ** Calls related to file-locks are passed on to the real file handle. | 505 ** Calls related to file-locks are passed on to the real file handle. |
497 */ | 506 */ |
498 static int cfLock(sqlite3_file *pFile, int eLock){ | 507 static int cfLock(sqlite3_file *pFile, int eLock){ |
499 return sqlite3OsLock(((CrashFile *)pFile)->pRealFile, eLock); | 508 return sqlite3OsLock(((CrashFile *)pFile)->pRealFile, eLock); |
500 } | 509 } |
501 static int cfUnlock(sqlite3_file *pFile, int eLock){ | 510 static int cfUnlock(sqlite3_file *pFile, int eLock){ |
502 return sqlite3OsUnlock(((CrashFile *)pFile)->pRealFile, eLock); | 511 return sqlite3OsUnlock(((CrashFile *)pFile)->pRealFile, eLock); |
503 } | 512 } |
504 static int cfCheckReservedLock(sqlite3_file *pFile, int *pResOut){ | 513 static int cfCheckReservedLock(sqlite3_file *pFile, int *pResOut){ |
505 return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut); | 514 return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut); |
506 } | 515 } |
507 static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){ | 516 static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){ |
| 517 if( op==SQLITE_FCNTL_SIZE_HINT ){ |
| 518 CrashFile *pCrash = (CrashFile *)pFile; |
| 519 i64 nByte = *(i64 *)pArg; |
| 520 if( nByte>pCrash->iSize ){ |
| 521 if( SQLITE_OK==writeListAppend(pFile, nByte, 0, 0) ){ |
| 522 pCrash->iSize = (int)nByte; |
| 523 } |
| 524 } |
| 525 return SQLITE_OK; |
| 526 } |
508 return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg); | 527 return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg); |
509 } | 528 } |
510 | 529 |
511 /* | 530 /* |
512 ** The xSectorSize() and xDeviceCharacteristics() functions return | 531 ** The xSectorSize() and xDeviceCharacteristics() functions return |
513 ** the global values configured by the [sqlite_crashparams] tcl | 532 ** the global values configured by the [sqlite_crashparams] tcl |
514 * interface. | 533 * interface. |
515 */ | 534 */ |
516 static int cfSectorSize(sqlite3_file *pFile){ | 535 static int cfSectorSize(sqlite3_file *pFile){ |
517 return g.iSectorSize; | 536 return g.iSectorSize; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 if( rc==SQLITE_OK ){ | 615 if( rc==SQLITE_OK ){ |
597 i64 iSize; | 616 i64 iSize; |
598 pWrapper->pMethod = &CrashFileVtab; | 617 pWrapper->pMethod = &CrashFileVtab; |
599 pWrapper->zName = (char *)zName; | 618 pWrapper->zName = (char *)zName; |
600 pWrapper->pRealFile = pReal; | 619 pWrapper->pRealFile = pReal; |
601 rc = sqlite3OsFileSize(pReal, &iSize); | 620 rc = sqlite3OsFileSize(pReal, &iSize); |
602 pWrapper->iSize = (int)iSize; | 621 pWrapper->iSize = (int)iSize; |
603 pWrapper->flags = flags; | 622 pWrapper->flags = flags; |
604 } | 623 } |
605 if( rc==SQLITE_OK ){ | 624 if( rc==SQLITE_OK ){ |
606 pWrapper->nData = (4096 + pWrapper->iSize); | 625 pWrapper->nData = (int)(4096 + pWrapper->iSize); |
607 pWrapper->zData = crash_malloc(pWrapper->nData); | 626 pWrapper->zData = crash_malloc(pWrapper->nData); |
608 if( pWrapper->zData ){ | 627 if( pWrapper->zData ){ |
609 /* os_unix.c contains an assert() that fails if the caller attempts | 628 /* os_unix.c contains an assert() that fails if the caller attempts |
610 ** to read data from the 512-byte locking region of a file opened | 629 ** to read data from the 512-byte locking region of a file opened |
611 ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file | 630 ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file |
612 ** never contains valid data anyhow. So avoid doing such a read here. | 631 ** never contains valid data anyhow. So avoid doing such a read here. |
| 632 ** |
| 633 ** UPDATE: It also contains an assert() verifying that each call |
| 634 ** to the xRead() method reads less than 128KB of data. |
613 */ | 635 */ |
614 const int isDb = (flags&SQLITE_OPEN_MAIN_DB); | 636 i64 iOff; |
615 i64 iChunk = pWrapper->iSize; | 637 |
616 if( iChunk>PENDING_BYTE && isDb ){ | |
617 iChunk = PENDING_BYTE; | |
618 } | |
619 memset(pWrapper->zData, 0, pWrapper->nData); | 638 memset(pWrapper->zData, 0, pWrapper->nData); |
620 rc = sqlite3OsRead(pReal, pWrapper->zData, iChunk, 0); | 639 for(iOff=0; iOff<pWrapper->iSize; iOff += 512){ |
621 if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){ | 640 int nRead = (int)(pWrapper->iSize - iOff); |
622 i64 iOff = PENDING_BYTE+512; | 641 if( nRead>512 ) nRead = 512; |
623 iChunk = pWrapper->iSize - iOff; | 642 rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff); |
624 rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], iChunk, iOff); | |
625 } | 643 } |
626 }else{ | 644 }else{ |
627 rc = SQLITE_NOMEM; | 645 rc = SQLITE_NOMEM; |
628 } | 646 } |
629 } | 647 } |
630 if( rc!=SQLITE_OK && pWrapper->pMethod ){ | 648 if( rc!=SQLITE_OK && pWrapper->pMethod ){ |
631 sqlite3OsClose(pFile); | 649 sqlite3OsClose(pFile); |
632 } | 650 } |
633 return rc; | 651 return rc; |
634 } | 652 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 Tcl_Interp *interp, | 706 Tcl_Interp *interp, |
689 int objc, | 707 int objc, |
690 Tcl_Obj *CONST objv[], | 708 Tcl_Obj *CONST objv[], |
691 int *piDeviceChar, | 709 int *piDeviceChar, |
692 int *piSectorSize | 710 int *piSectorSize |
693 ){ | 711 ){ |
694 struct DeviceFlag { | 712 struct DeviceFlag { |
695 char *zName; | 713 char *zName; |
696 int iValue; | 714 int iValue; |
697 } aFlag[] = { | 715 } aFlag[] = { |
698 { "atomic", SQLITE_IOCAP_ATOMIC }, | 716 { "atomic", SQLITE_IOCAP_ATOMIC }, |
699 { "atomic512", SQLITE_IOCAP_ATOMIC512 }, | 717 { "atomic512", SQLITE_IOCAP_ATOMIC512 }, |
700 { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, | 718 { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, |
701 { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, | 719 { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, |
702 { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, | 720 { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, |
703 { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, | 721 { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, |
704 { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, | 722 { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, |
705 { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, | 723 { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, |
706 { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, | 724 { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, |
707 { "sequential", SQLITE_IOCAP_SEQUENTIAL }, | 725 { "sequential", SQLITE_IOCAP_SEQUENTIAL }, |
708 { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, | 726 { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, |
| 727 { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, |
709 { 0, 0 } | 728 { 0, 0 } |
710 }; | 729 }; |
711 | 730 |
712 int i; | 731 int i; |
713 int iDc = 0; | 732 int iDc = 0; |
714 int iSectorSize = 0; | 733 int iSectorSize = 0; |
715 int setSectorsize = 0; | 734 int setSectorsize = 0; |
716 int setDeviceChar = 0; | 735 int setDeviceChar = 0; |
717 | 736 |
718 for(i=0; i<objc; i+=2){ | 737 for(i=0; i<objc; i+=2){ |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); | 1010 Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); |
992 Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); | 1011 Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); |
993 Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); | 1012 Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); |
994 Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); | 1013 Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); |
995 Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); | 1014 Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); |
996 #endif | 1015 #endif |
997 return TCL_OK; | 1016 return TCL_OK; |
998 } | 1017 } |
999 | 1018 |
1000 #endif /* SQLITE_TEST */ | 1019 #endif /* SQLITE_TEST */ |
OLD | NEW |