Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enable async testing. Modify the OS layer interface. Add the sqlite3_aux.h include file. Add tests for boolean value representation in file format 4. (CVS 2866) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b8332aa8b83142898779972b3dff13cb |
User & Date: | drh 2006-01-06 03:29:57.000 |
Context
2006-01-06
| ||
06:33 | Fix a bug that was emptying shared-schema tables during an ATTACH. (CVS 2867) (check-in: 752a275487 user: danielk1977 tags: trunk) | |
03:29 | Enable async testing. Modify the OS layer interface. Add the sqlite3_aux.h include file. Add tests for boolean value representation in file format 4. (CVS 2866) (check-in: b8332aa8b8 user: drh tags: trunk) | |
01:42 | Formatting changes in btree.c. (CVS 2865) (check-in: f1922da2d2 user: drh tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h # Header files used by the VDBE submodule # VDBEHDR = \ $(HDR) \ | > > | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test_async.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/sqlite3_aux.h \ $(TOP)/src/vdbe.h \ parse.h # Header files used by the VDBE submodule # VDBEHDR = \ $(HDR) \ |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # $(TOP)/src/test_async.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h # Header files used by the VDBE submodule # VDBEHDR = \ $(HDR) \ | > > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test_async.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # $(TOP)/src/test_async.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ $(TOP)/src/hash.h \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/sqlite3_aux.h \ $(TOP)/src/vdbe.h \ parse.h # Header files used by the VDBE submodule # VDBEHDR = \ $(HDR) \ |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 | } int sqlite3OsLockState(OsFile *id){ return id->pMethod->xLockState(id); } int sqlite3OsCheckReservedLock(OsFile *id){ return id->pMethod->xCheckReservedLock(id); } | | < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | 65 66 67 68 69 70 71 72 73 74 | } int sqlite3OsLockState(OsFile *id){ return id->pMethod->xLockState(id); } int sqlite3OsCheckReservedLock(OsFile *id){ return id->pMethod->xCheckReservedLock(id); } struct sqlite3OsVtbl *sqlite3_os_switch(void){ return &sqlite3Os; } |
Changes to src/os.h.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ** ** This header file (together with is companion C source-code file ** "os.c") attempt to abstract the underlying operating system so that ** the SQLite library will work on both POSIX and windows systems. */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ /* ** Figure out if we are dealing with Unix, Windows or MacOS. ** ** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix. ** The MacOS build is designed to use CodeWarrior (tested with v8) */ | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This header file (together with is companion C source-code file ** "os.c") attempt to abstract the underlying operating system so that ** the SQLite library will work on both POSIX and windows systems. */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ #include "sqlite3_aux.h" /* ** Figure out if we are dealing with Unix, Windows or MacOS. ** ** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix. ** The MacOS build is designed to use CodeWarrior (tested with v8) */ |
︙ | ︙ | |||
39 40 41 42 43 44 45 | #else # ifndef OS_WIN # define OS_WIN 0 # endif #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #else # ifndef OS_WIN # define OS_WIN 0 # endif #endif /* ** Define the maximum size of a temporary filename */ #if OS_WIN # include <windows.h> # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) #else |
︙ | ︙ | |||
108 109 110 111 112 113 114 | ** prematurely, old temporary files can be easily identified. This can be done ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. */ #ifndef TEMP_FILE_PREFIX # define TEMP_FILE_PREFIX "sqlite_" #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 70 71 72 73 74 75 76 77 78 79 | ** prematurely, old temporary files can be easily identified. This can be done ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. */ #ifndef TEMP_FILE_PREFIX # define TEMP_FILE_PREFIX "sqlite_" #endif #endif /* _SQLITE_OS_H_ */ |
Added src/sqlite3_aux.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | /* ** 2006 January 05 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines auxiliary interfaces to the SQLite library. ** This header file is a companion to the official "sqlite.h" interface ** file. The difference is that the extraordinary efforts are made to ** insure that the interface defined in "sqlite.h" is always backwards ** compatible. No such guarantees are made for the auxiliary interfaces ** defined in this header file. The interfaces defined here are subject ** to change in future releases of SQLite. ** ** We justify the volitility of the interfaces defined here by noting that ** these interfaces are designed not for users of the SQLite library but ** by code that wishes to expand and extend the SQLite library. Some ** knowledge of what SQLite is doing internally is necessary to use these ** interfaces. ** ** We have no intention of changing the interfaces defined in this file ** gratuitously. No interfaces will be changed without good reason. But ** on the other hand, if the quality and functionality of SQLite can be ** enhanced by modifying the interfaces found here, then we will do so. ** ** Since these interfaces are variable, it is suggested that they not ** be accessed as a shared library. Users of these interfaces should ** statically link. ** ** @(#) $Id: sqlite3_aux.h,v 1.1 2006/01/06 03:29:58 drh Exp $ */ /* ** Forward declarations */ typedef struct OsFile OsFile; typedef struct IoMethod IoMethod; /* ** An instance of the following structure contains pointers to all ** methods on an OsFile object. */ struct IoMethod { int (*xClose)(OsFile**); int (*xOpenDirectory)(OsFile*, const char*); int (*xRead)(OsFile*, void*, int amt); int (*xWrite)(OsFile*, const void*, int amt); int (*xSeek)(OsFile*, i64 offset); int (*xTruncate)(OsFile*, i64 size); int (*xSync)(OsFile*, int); void (*xSetFullSync)(OsFile *id, int setting); int (*xFileHandle)(OsFile *id); int (*xFileSize)(OsFile*, i64 *pSize); int (*xLock)(OsFile*, int); int (*xUnlock)(OsFile*, int); int (*xLockState)(OsFile *id); int (*xCheckReservedLock)(OsFile *id); }; /* ** The OsFile object describes an open disk file in an OS-dependent way. ** The version of OsFile defined here is a generic version. Each OS ** implementation defines its own subclass of this structure that contains ** additional information needed to handle file I/O. But the pMethod ** entry (pointing to the virtual function table) always occurs first ** so that we can always find the appropriate methods. */ struct OsFile { IoMethod const *pMethod; }; /* ** The following values may be passed as the second argument to ** sqlite3OsLock(). The various locks exhibit the following semantics: ** ** SHARED: Any number of processes may hold a SHARED lock simultaneously. ** RESERVED: A single process may hold a RESERVED lock on a file at ** any time. Other processes may hold and obtain new SHARED locks. ** PENDING: A single process may hold a PENDING lock on a file at ** any one time. Existing SHARED locks may persist, but no new ** SHARED locks may be obtained by other processes. ** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. ** ** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a ** process that requests an EXCLUSIVE lock may actually obtain a PENDING ** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to ** sqlite3OsLock(). */ #define NO_LOCK 0 #define SHARED_LOCK 1 #define RESERVED_LOCK 2 #define PENDING_LOCK 3 #define EXCLUSIVE_LOCK 4 /* ** File Locking Notes: (Mostly about windows but also some info for Unix) ** ** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because ** those functions are not available. So we use only LockFile() and ** UnlockFile(). ** ** LockFile() prevents not just writing but also reading by other processes. ** A SHARED_LOCK is obtained by locking a single randomly-chosen ** byte out of a specific range of bytes. The lock byte is obtained at ** random so two separate readers can probably access the file at the ** same time, unless they are unlucky and choose the same lock byte. ** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. ** There can only be one writer. A RESERVED_LOCK is obtained by locking ** a single byte of the file that is designated as the reserved lock byte. ** A PENDING_LOCK is obtained by locking a designated byte different from ** the RESERVED_LOCK byte. ** ** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, ** which means we can use reader/writer locks. When reader/writer locks ** are used, the lock is placed on the same range of bytes that is used ** for probabilistic locking in Win95/98/ME. Hence, the locking scheme ** will support two or more Win95 readers or two or more WinNT readers. ** But a single Win95 reader will lock out all WinNT readers and a single ** WinNT reader will lock out all other Win95 readers. ** ** The following #defines specify the range of bytes used for locking. ** SHARED_SIZE is the number of bytes available in the pool from which ** a random byte is selected for a shared lock. The pool of bytes for ** shared locks begins at SHARED_FIRST. ** ** These #defines are available in sqlite_aux.h so that adaptors for ** connecting SQLite to other operating systems can use the same byte ** ranges for locking. In particular, the same locking strategy and ** byte ranges are used for Unix. This leaves open the possiblity of having ** clients on win95, winNT, and unix all talking to the same shared file ** and all locking correctly. To do so would require that samba (or whatever ** tool is being used for file sharing) implements locks correctly between ** windows and unix. I'm guessing that isn't likely to happen, but by ** using the same locking range we are at least open to the possibility. ** ** Locking in windows is manditory. For this reason, we cannot store ** actual data in the bytes used for locking. The pager never allocates ** the pages involved in locking therefore. SHARED_SIZE is selected so ** that all locks will fit on a single page even at the minimum page size. ** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE ** is set high so that we don't have to allocate an unused page except ** for very large databases. But one should test the page skipping logic ** by setting PENDING_BYTE low and running the entire regression suite. ** ** Changing the value of PENDING_BYTE results in a subtly incompatible ** file format. Depending on how it is changed, you might not notice ** the incompatibility right away, even running a full regression test. ** The default location of PENDING_BYTE is the first byte past the ** 1GB boundary. ** */ #ifndef SQLITE_TEST #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ #else extern unsigned int sqlite3_pending_byte; #define PENDING_BYTE sqlite3_pending_byte #endif #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 /* ** A single global instance of the following structure holds pointers to ** the routines that SQLite uses to talk with the underlying operating ** system. Clever programmers can substitute alternative implementations ** of these routine (prior to using any SQLite API!) in order to modify ** the way SQLite interacts with its environment. For example, modifications ** could be supplied that allow SQLite to talk to a virtual file system. */ extern struct sqlite3OsVtbl { int (*xOpenReadWrite)(const char*, OsFile**, int*); int (*xOpenExclusive)(const char*, OsFile**, int); int (*xOpenReadOnly)(const char*, OsFile**); int (*xDelete)(const char*); int (*xFileExists)(const char*); char *(*xFullPathname)(const char*); int (*xIsDirWritable)(char*); int (*xSyncDirectory)(const char*); int (*xTempFileName)(char*); int (*xRandomSeed)(char*); int (*xSleep)(int ms); int (*xCurrentTime)(double*); void (*xEnterMutex)(void); void (*xLeaveMutex)(void); int (*xInMutex)(void); void *(*xThreadSpecificData)(int); void *(*xMalloc)(int); void *(*xRealloc)(void *, int); void (*xFree)(void *); int (*xAllocationSize)(void *); } sqlite3Os; /* ** The following API routine returns a pointer to the sqlite3Os global ** variable. It is probably easier just to reference the global variable ** directly. This routine is provided for backwards compatibility with ** an older interface design. */ struct sqlite3OsVtbl *sqlite3_os_switch(void); /* ** The following are prototypes of convenience routines that simply ** call the corresponding routines in the OsFile.pMethod virtual ** function table. */ int sqlite3OsClose(OsFile**); int sqlite3OsOpenDirectory(OsFile*, const char*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); int sqlite3OsSeek(OsFile*, i64 offset); int sqlite3OsTruncate(OsFile*, i64 size); int sqlite3OsSync(OsFile*, int); void sqlite3OsSetFullSync(OsFile *id, int setting); int sqlite3OsFileHandle(OsFile *id); int sqlite3OsFileSize(OsFile*, i64 *pSize); int sqlite3OsLock(OsFile*, int); int sqlite3OsUnlock(OsFile*, int); int sqlite3OsLockState(OsFile *id); int sqlite3OsCheckReservedLock(OsFile *id); |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.146 2006/01/06 03:29:58 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
2157 2158 2159 2160 2161 2162 2163 | Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); | | | 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 | Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetestasync_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ |
︙ | ︙ |
Changes to src/test_async.c.
︙ | ︙ | |||
231 232 233 234 235 236 237 | ** to sqlite3_async_flush() is responsible for calling sqliteFree(). ** ** Once an AsyncWrite structure has been added to the list, it must not be ** read or modified by the caller (in case another thread calls ** sqlite3_async_flush() ). */ static void addAsyncWrite(AsyncWrite *pWrite){ | | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | ** to sqlite3_async_flush() is responsible for calling sqliteFree(). ** ** Once an AsyncWrite structure has been added to the list, it must not be ** read or modified by the caller (in case another thread calls ** sqlite3_async_flush() ). */ static void addAsyncWrite(AsyncWrite *pWrite){ sqlite3Os.xEnterMutex(); assert( !pWrite->pNext ); if( sqlite3_asyncListLast ){ assert( sqlite3_asyncListFirst ); sqlite3_asyncListLast->pNext = pWrite; }else{ sqlite3_asyncListFirst = pWrite; } sqlite3_asyncListLast = pWrite; sqlite3Os.xLeaveMutex(); } /* ** The caller should already hold the mutex when this is called. */ static void removeAsyncWrite(AsyncWrite *p){ assert( p==sqlite3_asyncListFirst ); |
︙ | ︙ | |||
356 357 358 359 360 361 362 | static int asyncRead(OsFile *id, void *obuf, int amt){ int rc = SQLITE_OK; i64 filesize; int nRead; AsyncFile *pFile = (AsyncFile *)id; /* Grab the mutex for the duration of the call */ | | | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | static int asyncRead(OsFile *id, void *obuf, int amt){ int rc = SQLITE_OK; i64 filesize; int nRead; AsyncFile *pFile = (AsyncFile *)id; /* Grab the mutex for the duration of the call */ sqlite3Os.xEnterMutex(); if( pFile->pBaseRead ){ rc = sqlite3OsFileSize(pFile->pBaseRead, &filesize); if( rc!=SQLITE_OK ){ goto asyncread_out; } rc = sqlite3OsSeek(pFile->pBaseRead, pFile->iOffset); |
︙ | ︙ | |||
397 398 399 400 401 402 403 | } } pFile->iOffset += (i64)amt; } asyncread_out: | | | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | } } pFile->iOffset += (i64)amt; } asyncread_out: sqlite3Os.xLeaveMutex(); return rc; } /* ** Seek to the specified offset. This just adjusts the AsyncFile.iOffset ** variable - calling seek() on the underlying file is defered until the ** next read() or write() operation. |
︙ | ︙ | |||
423 424 425 426 427 428 429 | ** ** This method holds the mutex from start to finish. */ int asyncFileSize(OsFile *id, i64 *pSize){ int rc = SQLITE_OK; i64 s = 0; OsFile *pBase; | | | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | ** ** This method holds the mutex from start to finish. */ int asyncFileSize(OsFile *id, i64 *pSize){ int rc = SQLITE_OK; i64 s = 0; OsFile *pBase; sqlite3Os.xEnterMutex(); /* Read the filesystem size from the base file. If pBaseRead is NULL, this ** means the file hasn't been opened yet. In this case all relevant data ** must be in the write-op queue anyway, so we can omit reading from the ** file-system. */ pBase = ((AsyncFile *)id)->pBaseRead; |
︙ | ︙ | |||
451 452 453 454 455 456 457 | s = MIN(s, p->nByte); break; } } } *pSize = s; } | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | s = MIN(s, p->nByte); break; } } } *pSize = s; } sqlite3Os.xLeaveMutex(); return rc; } /* ** Return the operating system file handle. This is only used for debugging ** at the moment anyway. */ |
︙ | ︙ | |||
618 619 620 621 622 623 624 | ** in the file system. ** ** This method holds the mutex from start to finish. */ static int asyncFileExists(const char *z){ int ret; AsyncWrite *p; | | | < < < < < < | | | | | | < < < > | < < | < | > > | | | 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | ** in the file system. ** ** This method holds the mutex from start to finish. */ static int asyncFileExists(const char *z){ int ret; AsyncWrite *p; sqlite3Os.xEnterMutex(); /* See if the real file system contains the specified file. */ ret = xOrigFileExists(z); for(p=sqlite3_asyncListFirst; p; p = p->pNext){ if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, z) ){ ret = 0; }else if( p->op==ASYNC_OPENEXCLUSIVE && 0==strcmp(p->zBuf, z) ){ ret = 1; } } sqlite3Os.xLeaveMutex(); return ret; } /* ** The following routine is one of two exported symbols in this module (along ** with sqlite3_async_flush(), see below). This routine should be called ** once to enable the asynchronous IO features implemented in this file. If ** the features are successfully enabled (or if they have already been ** enabled) then SQLITE_OK is returned. Otherwise, SQLITE_MISUSE. */ int sqlite3_async_enable(void){ if( xOrigOpenReadWrite==0 ){ xOrigOpenReadWrite = sqlite3Os.xOpenReadWrite; xOrigOpenReadOnly = sqlite3Os.xOpenReadOnly; xOrigOpenExclusive = sqlite3Os.xOpenExclusive; xOrigDelete = sqlite3Os.xDelete; xOrigFileExists = sqlite3Os.xFileExists; xOrigSyncDirectory = sqlite3Os.xSyncDirectory; sqlite3Os.xOpenReadWrite = asyncOpenReadWrite; sqlite3Os.xOpenReadOnly = asyncOpenReadOnly; sqlite3Os.xOpenExclusive = asyncOpenExclusive; sqlite3Os.xDelete = asyncDelete; sqlite3Os.xFileExists = asyncFileExists; sqlite3Os.xSyncDirectory = asyncSyncDirectory; } return SQLITE_OK; } /* ** This function is called externally to perform queued write and sync ** operations. It returns when an IO error occurs or there are no more queued ** operations to perform. */ int sqlite3_async_flush(void){ AsyncWrite *p = 0; int rc = SQLITE_OK; /* Grab the mutex and set the sqlite3_asyncIoBusy flag to make sure this ** is the only thread performing an sqlite3_async_flush() at this time. ** Or, if some other thread is already inside this function, return ** SQLITE_BUSY to the caller. */ sqlite3Os.xEnterMutex(); if( sqlite3_asyncIoBusy ){ sqlite3Os.xLeaveMutex(); return SQLITE_BUSY; } sqlite3_asyncIoBusy = 1; while( (p = sqlite3_asyncListFirst) && rc==SQLITE_OK ){ int isInsideMutex = 1; |
︙ | ︙ | |||
720 721 722 723 724 725 726 | if( p->pFile ){ pBase = p->pFile->pBaseWrite; if( p->op==ASYNC_CLOSE || p->op==ASYNC_OPENEXCLUSIVE || (pBase && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) ){ | | | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | if( p->pFile ){ pBase = p->pFile->pBaseWrite; if( p->op==ASYNC_CLOSE || p->op==ASYNC_OPENEXCLUSIVE || (pBase && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) ){ sqlite3Os.xLeaveMutex(); isInsideMutex = 0; } if( !pBase ){ pBase = p->pFile->pBaseRead; } } |
︙ | ︙ | |||
777 778 779 780 781 782 783 | case ASYNC_OPENEXCLUSIVE: { AsyncFile *pFile = p->pFile; int delFlag = ((p->iOffset)?1:0); OsFile *pBase = 0; rc = xOrigOpenExclusive(p->zBuf, &pBase, delFlag); | | | | | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 | case ASYNC_OPENEXCLUSIVE: { AsyncFile *pFile = p->pFile; int delFlag = ((p->iOffset)?1:0); OsFile *pBase = 0; rc = xOrigOpenExclusive(p->zBuf, &pBase, delFlag); sqlite3Os.xEnterMutex(); isInsideMutex = 1; if( rc==SQLITE_OK ){ pFile->pBaseRead = pBase; } break; } default: assert(!"Illegal value for AsyncWrite.op"); } /* If we didn't hang on to the mutex during the IO op, obtain it now ** so that the AsyncWrite structure can be safely removed from the ** global write-op queue. */ if( !isInsideMutex ){ sqlite3Os.xEnterMutex(); } if( rc==SQLITE_OK ){ removeAsyncWrite(p); sqlite3Os.xFree(p); } } /* Clear the io-busy flag and exit the mutex */ assert( sqlite3_asyncIoBusy ); sqlite3_asyncIoBusy = 0; sqlite3Os.xLeaveMutex(); return rc; } /* ** The following code defines a Tcl interface for testing the asynchronous ** IO implementation in this file. |
︙ | ︙ | |||
922 923 924 925 926 927 928 | int Sqlitetestasync_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp,"sqlite3_async_enable",testAsyncEnable,0,0); Tcl_CreateObjCommand(interp,"sqlite3_async_flush",testAsyncFlush,0,0); return TCL_OK; } #endif | < | 913 914 915 916 917 918 919 | int Sqlitetestasync_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp,"sqlite3_async_enable",testAsyncEnable,0,0); Tcl_CreateObjCommand(interp,"sqlite3_async_flush",testAsyncFlush,0,0); return TCL_OK; } #endif |
Added test/format4.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # 2005 December 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to verify that the new serial_type # values of 8 (integer 0) and 9 (integer 1) work correctly. # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test format4-1.1 { execsql { CREATE TABLE t1(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); INSERT INTO t1 VALUES(0,0,0,0,0,0,0,0,0,0); INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; } file size test.db } {2048} do_test format4-1.2 { execsql { UPDATE t1 SET x0=1, x1=1, x2=1, x3=1, x4=1, x5=1, x6=1, x7=1, x8=1, x9=1 } file size test.db } {2048} do_test format4-1.3 { execsql { UPDATE t1 SET x0=2, x1=2, x2=2, x3=2, x4=2, x5=2, x6=2, x7=2, x8=2, x9=2 } file size test.db } {4096} finish_test |