Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Progress towards getting locking to work on windows. (CVS 1536) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4f7c0961ad6cb7082bf7716f0c7ca16a |
User & Date: | drh 2004-06-07 01:52:14.000 |
Context
2004-06-07
| ||
07:52 | Add pragma to set/get text encoding. Also fix an obscure problem where a temp trigger could be accidently dropped. (CVS 1537) (check-in: 983221b038 user: danielk1977 tags: trunk) | |
01:52 | Progress towards getting locking to work on windows. (CVS 1536) (check-in: 4f7c0961ad user: drh tags: trunk) | |
2004-06-06
| ||
12:41 | Performance improvements for LIKE. It is still too slow though. (CVS 1535) (check-in: 30b81507fc user: danielk1977 tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.160 2004/06/07 01:52:14 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
2262 2263 2264 2265 2266 2267 2268 | /* ** The TRACE macro will print high-level status information about the ** btree operation when the global variable sqlite3_btree_trace is ** enabled. */ #if SQLITE_TEST | | > | 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 | /* ** The TRACE macro will print high-level status information about the ** btree operation when the global variable sqlite3_btree_trace is ** enabled. */ #if SQLITE_TEST # define TRACE(X) if( sqlite3_btree_trace )\ { sqlite3DebugPrintf X; fflush(stdout); } #else # define TRACE(X) #endif int sqlite3_btree_trace=0; /* True to enable tracing */ /* ** Allocate a new page from the database file. |
︙ | ︙ |
Changes to src/os_common.h.
︙ | ︙ | |||
33 34 35 36 37 38 39 | return x; } static unsigned long long int g_start; static unsigned int elapse; #define TIMER_START g_start=hwtime() #define TIMER_END elapse=hwtime()-g_start #define SEEK(X) last_page=(X) | | | | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | return x; } static unsigned long long int g_start; static unsigned int elapse; #define TIMER_START g_start=hwtime() #define TIMER_END elapse=hwtime()-g_start #define SEEK(X) last_page=(X) #define TRACE1(X) sqlite3DebugPrintf(X) #define TRACE2(X,Y) sqlite3DebugPrintf(X,Y) #define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) #define TRACE4(X,Y,Z,A) sqlite3DebugPrintf(X,Y,Z,A) #define TRACE5(X,Y,Z,A,B) sqlite3DebugPrintf(X,Y,Z,A,B) #else #define TIMER_START #define TIMER_END #define SEEK(X) #define TRACE1(X) #define TRACE2(X,Y) #define TRACE3(X,Y,Z) |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
86 87 88 89 90 91 92 93 94 95 96 97 98 99 | } *pReadonly = 1; }else{ *pReadonly = 0; } id->h = h; id->locktype = NO_LOCK; OpenCounter(+1); TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* | > | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | } *pReadonly = 1; }else{ *pReadonly = 0; } id->h = h; id->locktype = NO_LOCK; id->sharedLockByte = 0; OpenCounter(+1); TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* |
︙ | ︙ | |||
128 129 130 131 132 133 134 135 136 137 138 139 140 141 | NULL ); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } id->h = h; id->locktype = NO_LOCK; OpenCounter(+1); TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* ** Attempt to open a new file for read-only access. | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | NULL ); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } id->h = h; id->locktype = NO_LOCK; id->sharedLockByte = 0; OpenCounter(+1); TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* ** Attempt to open a new file for read-only access. |
︙ | ︙ | |||
154 155 156 157 158 159 160 161 162 163 164 165 166 167 | NULL ); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } id->h = h; id->locktype = NO_LOCK; OpenCounter(+1); TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* ** Attempt to open a file descriptor for the directory that contains a | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | NULL ); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } id->h = h; id->locktype = NO_LOCK; id->sharedLockByte = 0; OpenCounter(+1); TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); return SQLITE_OK; } /* ** Attempt to open a file descriptor for the directory that contains a |
︙ | ︙ | |||
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | return SQLITE_OK; } /* ** Close a file. */ int sqlite3OsClose(OsFile *id){ CloseHandle(id->h); OpenCounter(-1); return SQLITE_OK; } /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ DWORD got; SimulateIOError(SQLITE_IOERR); | > | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | return SQLITE_OK; } /* ** Close a file. */ int sqlite3OsClose(OsFile *id){ TRACE2("CLOSE %d\n", id->h); CloseHandle(id->h); OpenCounter(-1); return SQLITE_OK; } /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ DWORD got; SimulateIOError(SQLITE_IOERR); TRACE3("READ %d lock=%d\n", id->h, id->locktype); if( !ReadFile(id->h, pBuf, amt, &got, 0) ){ got = 0; } if( got==(DWORD)amt ){ return SQLITE_OK; }else{ return SQLITE_IOERR; } } /* ** Write data from a buffer into a file. Return SQLITE_OK on success ** or some other error code on failure. */ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ int rc; DWORD wrote; SimulateIOError(SQLITE_IOERR); TRACE3("WRITE %d lock=%d\n", id->h, id->locktype); while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; } if( !rc || amt>(int)wrote ){ return SQLITE_FULL; } |
︙ | ︙ | |||
274 275 276 277 278 279 280 | return SQLITE_OK; } /* ** Make sure all writes to a particular file are committed to disk. */ int sqlite3OsSync(OsFile *id){ | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | return SQLITE_OK; } /* ** Make sure all writes to a particular file are committed to disk. */ int sqlite3OsSync(OsFile *id){ TRACE3("SYNC %d lock=%d\n", id->h, id->locktype); if( FlushFileBuffers(id->h) ){ return SQLITE_OK; }else{ return SQLITE_IOERR; } } |
︙ | ︙ | |||
342 343 344 345 346 347 348 | ** ** 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. */ #define SHARED_SIZE 10238 | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | ** ** 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. */ #define SHARED_SIZE 10238 #define SHARED_FIRST (0x3fffffff - (SHARED_SIZE - 1)) #define RESERVED_BYTE (SHARED_FIRST - 1) #define PENDING_BYTE (RESERVED_BYTE - 1) /* ** Return true (non-zero) if we are running under WinNT, Win2K or WinXP. ** Return false (zero) for Win95, Win98, or WinME. ** |
︙ | ︙ | |||
409 410 411 412 413 414 415 416 | ** appropriate lock already exists, this routine is a no-op. Return ** SQLITE_OK on success and SQLITE_BUSY if another thread is already ** holding a conflicting lock. */ int sqlite3OsLock(OsFile *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ int res = 1; /* Result of a windows lock call */ | > > > | | > > > > | | | > > > > > > > > > > | > > > > > > > > > > > > > > < | > > | | | > | | | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | ** appropriate lock already exists, this routine is a no-op. Return ** SQLITE_OK on success and SQLITE_BUSY if another thread is already ** holding a conflicting lock. */ int sqlite3OsLock(OsFile *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ int res = 1; /* Result of a windows lock call */ int newLocktype; /* Set id->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ TRACE5("LOCK %d %d was %d(%d)\n", id->h, locktype, id->locktype, id->sharedLockByte); /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as ** sqlite3OsEnterMutex() hasn't been called yet. */ if( id->locktype>=locktype ){ return SQLITE_OK; } /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ if( id->locktype==NO_LOCK || (locktype>=PENDING_LOCK && id->locktype<PENDING_LOCK) ){ int cnt = 4; while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 4 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. */ TRACE2("could not get a PENDING lock. cnt=%d\n", cnt); Sleep(1); } gotPendingLock = res; } /* Acquire a shared lock */ if( locktype>=SHARED_LOCK && id->locktype<SHARED_LOCK && res ){ if( isNT() ){ res = getReadLock(id->h, SHARED_FIRST, SHARED_SIZE); }else{ int lk; sqlite3Randomness(sizeof(lk), &lk); id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0); } if( res ){ newLocktype = SHARED_LOCK; } } /* Acquire a RESERVED lock */ if( locktype>=RESERVED_LOCK && id->locktype<RESERVED_LOCK && res ){ res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0); if( res ){ newLocktype = RESERVED_LOCK; } } /* Acquire a PENDING lock */ if( locktype>=PENDING_LOCK && res ){ newLocktype = PENDING_LOCK; gotPendingLock = 0; } /* Acquire an EXCLUSIVE lock */ if( locktype==EXCLUSIVE_LOCK && res ){ if( id->locktype>=SHARED_LOCK ){ res = unlockReadLock(id); TRACE2("unreadlock = %d\n", res); } if( res ){ res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0); }else{ TRACE2("LOCK FAILED due to failure to unlock read %d\n", id->h); res = 0; } if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ TRACE2("error-code = %d\n", GetLastError()); } } /* If we are holding a PENDING lock that ought to be released, then ** release it now. */ if( gotPendingLock && (res==0 || locktype<PENDING_LOCK) ){ UnlockFile(id->h, PENDING_BYTE, 0, 1, 0); } /* Update the state of the lock has held in the file descriptor then ** return the appropriate result code. */ if( res ){ rc = SQLITE_OK; }else{ TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h, locktype, newLocktype); rc = SQLITE_BUSY; } id->locktype = newLocktype; return rc; } /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ int sqlite3OsCheckWriteLock(OsFile *id){ int rc; if( id->locktype>=RESERVED_LOCK ){ rc = 1; }else{ rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0); } } return 0; } /* ** Unlock the given file descriptor. If the file descriptor was ** not previously locked, then this routine is a no-op. If this ** library was compiled with large file support (LFS) but LFS is not ** available on the host, then an SQLITE_NOLFS is returned. */ int sqlite3OsUnlock(OsFile *id){ int rc, type; TRACE4("UNLOCK %d was %d(%d)\n", id->h, id->locktype, id->sharedLockByte); type = id->locktype; if( type>=EXCLUSIVE_LOCK ){ UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0); } if( type>=PENDING_LOCK ){ UnlockFile(id->h, PENDING_BYTE, 0, 1, 0); } if( type>=RESERVED_LOCK ){ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0); } if( type>=SHARED_LOCK && type<EXCLUSIVE_LOCK ){ unlockReadLock(id); } id->locktype = NO_LOCK; return SQLITE_OK; } /* |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
794 795 796 797 798 799 800 801 802 803 804 805 806 807 | va_start(ap,zFormat); z = base_vprintf(0, 0, zBuf, n, zFormat, ap); va_end(ap); return z; } /* ** The following four routines implement the varargs versions of the ** sqlite3_exec() and sqlite3_get_table() interfaces. See the sqlite.h ** header files for a more detailed description of how these interfaces ** work. ** ** These routines are all just simple wrappers. | > > > > > > > > > > > > > > > > | 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | va_start(ap,zFormat); z = base_vprintf(0, 0, zBuf, n, zFormat, ap); va_end(ap); return z; } #ifndef NDEBUG /* ** A version of printf() that understands %lld. Used for debugging. ** The printf() built into some versions of windows does not understand %lld ** and segfaults if you give it a long long int. */ void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; char zBuf[500]; va_start(ap, zFormat); base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap); va_end(ap); fprintf(stderr,"%s", zBuf); } #endif /* ** The following four routines implement the varargs versions of the ** sqlite3_exec() and sqlite3_get_table() interfaces. See the sqlite.h ** header files for a more detailed description of how these interfaces ** work. ** ** These routines are all just simple wrappers. |
︙ | ︙ | |||
868 869 870 871 872 873 874 | int rc; zSql = sqlite3_vmprintf(sqlFormat, ap); rc = sqlite3_get_table(db, zSql, resultp, nrow, ncolumn, errmsg); free(zSql); return rc; } | < < < | 884 885 886 887 888 889 890 | int rc; zSql = sqlite3_vmprintf(sqlFormat, ap); rc = sqlite3_get_table(db, zSql, resultp, nrow, ncolumn, errmsg); free(zSql); return rc; } |
Changes to src/sqliteInt.h.
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. ** ************************************************************************* ** Internal interface definitions for 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.270 2004/06/07 01:52:14 drh Exp $ */ #include "config.h" #include "sqlite3.h" #include "hash.h" #include "parse.h" #include <stdio.h> #include <stdlib.h> |
︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 | void *sqliteRealloc(void*,int); char *sqliteStrDup(const char*); char *sqliteStrNDup(const char*, int); # define sqlite3CheckMemory(a,b) #endif char *sqlite3MPrintf(const char*, ...); char *sqlite3VMPrintf(const char*, va_list); void sqlite3SetString(char **, const char *, ...); void sqlite3SetNString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3Exec(Parse*); | > | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | void *sqliteRealloc(void*,int); char *sqliteStrDup(const char*); char *sqliteStrNDup(const char*, int); # define sqlite3CheckMemory(a,b) #endif char *sqlite3MPrintf(const char*, ...); char *sqlite3VMPrintf(const char*, va_list); void sqlite3DebugPrintf(const char*, ...); void sqlite3SetString(char **, const char *, ...); void sqlite3SetNString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3Exec(Parse*); |
︙ | ︙ |
Changes to test/attach.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach.test,v 1.22 2004/06/07 01:52:15 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl for {set i 2} {$i<=15} {incr i} { file delete -force test$i.db |
︙ | ︙ | |||
376 377 378 379 380 381 382 383 384 385 386 387 388 389 | catchsql {SELECT * FROM t1} } {1 {database is locked}} do_test attach-3.15 { execsql COMMIT db2 execsql {SELECT * FROM t1} } {1 2 3 4} # Ticket #323 do_test attach-4.1 { execsql {DETACH db2} db2 close sqlite db2 test2.db execsql { CREATE TABLE t3(x,y); | > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | catchsql {SELECT * FROM t1} } {1 {database is locked}} do_test attach-3.15 { execsql COMMIT db2 execsql {SELECT * FROM t1} } {1 2 3 4} #set btree_trace 1 #puts stderr "###################"; flush stderr # Ticket #323 do_test attach-4.1 { execsql {DETACH db2} db2 close sqlite db2 test2.db execsql { CREATE TABLE t3(x,y); |
︙ | ︙ |