Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(11)

Side by Side Diff: third_party/sqlite_google/src/btree.c

Issue 924: sqlite3 pragma get/set user_version implemented (Closed) SVN Base: http://google-gears.googlecode.com/svn/contrib/dimitri.glazkov/database2/gears/
Patch Set: moved code to btree.c, restructured Created 3 months, 2 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2004 April 6 2 ** 2004 April 6
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 **
11 ************************************************************************* 11 *************************************************************************
12 ** $Id: btree.c,v 1.388 2007/05/24 09:20:16 danielk1977 Exp $ 12 ** $Id: btree.c,v 1.388 2007/05/24 09:20:16 danielk1977 Exp $
13 ** 13 **
14 ** This file implements a external (disk-based) database using BTrees. 14 ** This file implements a external (disk-based) database using BTrees.
15 ** See the header comment on "btreeInt.h" for additional information. 15 ** See the header comment on "btreeInt.h" for additional information.
16 ** Including a description of file format and an overview of operation. 16 ** Including a description of file format and an overview of operation.
17 */ 17 */
18 #include "btreeInt.h" 18 #include "btreeInt.h"
19 19
20 /* 20 /*
21 ** The header string that appears at the beginning of every 21 ** The header string that appears at the beginning of every
22 ** SQLite database. 22 ** SQLite database.
23 */ 23 */
24 static const char zMagicHeader[] = SQLITE_FILE_HEADER; 24 static const char zMagicHeader[] = SQLITE_FILE_HEADER;
25 25
26 /* 26 /*
27 ** The header string that appears at the beginning of a SQLite 27 ** The header string that appears at the beginning of a SQLite
28 ** database which has been poisoned. 28 ** database which has been poisoned.
29 */ 29 */
30 static const char zPoisonHeader[] = "SQLite poison 3"; 30 static const char zPoisonHeader[] = "SQLite poison 3";
31 31
32 /*
33 ** The user cookie position in the database meta information
34 ** (see prepare.c#215), incremented by one, because first position is actually
35 ** the number of free pages in Btree (see vdbe.c#2521)
36 */
37 static const int kUserCookie = 6;
32 38
33 /* 39 /*
34 ** Set this global variable to 1 to enable tracing using the TRACE 40 ** Set this global variable to 1 to enable tracing using the TRACE
35 ** macro. 41 ** macro.
36 */ 42 */
37 #if SQLITE_TEST 43 #if SQLITE_TEST
38 int sqlite3_btree_trace=0; /* True to enable tracing */ 44 int sqlite3_btree_trace=0; /* True to enable tracing */
39 #endif 45 #endif
40 46
41 /* 47 /*
42 ** Forward declaration 48 ** Forward declaration
43 */ 49 */
44 static int checkReadLocks(Btree*,Pgno,BtCursor*); 50 static int checkReadLocks(Btree*,Pgno,BtCursor*);
45 51
46 52
47 #ifdef SQLITE_OMIT_SHARED_CACHE 53 #ifdef SQLITE_OMIT_SHARED_CACHE
48 /* 54 /*
49 ** The functions queryTableLock(), lockTable() and unlockAllTables() 55 ** The functions queryTableLock(), lockTable() and unlockAllTables()
50 ** manipulate entries in the BtShared.pLock linked list used to store 56 ** manipulate entries in the BtShared.pLock linked list used to store
51 ** shared-cache table level locks. If the library is compiled with the 57 ** shared-cache table level locks. If the library is compiled with the
52 ** shared-cache feature disabled, then there is only ever one user 58 ** shared-cache feature disabled, then there is only ever one user
53 ** of each BtShared structure and so this locking is not necessary. 59 ** of each BtShared structure and so this locking is not necessary.
54 ** So define the lock related functions as no-ops. 60 ** So define the lock related functions as no-ops.
55 */ 61 */
56 #define queryTableLock(a,b,c) SQLITE_OK 62 #define queryTableLock(a,b,c) SQLITE_OK
57 #define lockTable(a,b,c) SQLITE_OK 63 #define lockTable(a,b,c) SQLITE_OK
58 #define unlockAllTables(a) 64 #define unlockAllTables(a)
59 #else 65 #else
60 66
61 /* 67 /*
62 ** Query to see if btree handle p may obtain a lock of type eLock 68 ** Query to see if btree handle p may obtain a lock of type eLock
63 ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return 69 ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
64 ** SQLITE_OK if the lock may be obtained (by calling lockTable()), or 70 ** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
65 ** SQLITE_LOCKED if not. 71 ** SQLITE_LOCKED if not.
66 */ 72 */
67 static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ 73 static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
68 BtShared *pBt = p->pBt; 74 BtShared *pBt = p->pBt;
69 BtLock *pIter; 75 BtLock *pIter;
70 76
71 /* This is a no-op if the shared-cache is not enabled */ 77 /* This is a no-op if the shared-cache is not enabled */
72 if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){ 78 if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
73 return SQLITE_OK; 79 return SQLITE_OK;
74 } 80 }
75 81
76 /* This (along with lockTable()) is where the ReadUncommitted flag is 82 /* This (along with lockTable()) is where the ReadUncommitted flag is
77 ** dealt with. If the caller is querying for a read-lock and the flag is 83 ** dealt with. If the caller is querying for a read-lock and the flag is
78 ** set, it is unconditionally granted - even if there are write-locks 84 ** set, it is unconditionally granted - even if there are write-locks
79 ** on the table. If a write-lock is requested, the ReadUncommitted flag 85 ** on the table. If a write-lock is requested, the ReadUncommitted flag
80 ** is not considered. 86 ** is not considered.
81 ** 87 **
(...skipping 6293 matching lines...) Show 10 above Show 10 below
6375 ** to allow poisoning to be rolled back, and the database is anyhow 6381 ** to allow poisoning to be rolled back, and the database is anyhow
6376 ** going bye-bye RSN. 6382 ** going bye-bye RSN.
6377 */ 6383 */
6378 /* TODO(shess): Figure out if this might release the lock and let 6384 /* TODO(shess): Figure out if this might release the lock and let
6379 ** someone else get in there, which might deny us the lock a couple 6385 ** someone else get in there, which might deny us the lock a couple
6380 ** lines down. 6386 ** lines down.
6381 */ 6387 */
6382 if( sqlite3BtreeIsInTrans(p) ) sqlite3BtreeRollback(p); 6388 if( sqlite3BtreeIsInTrans(p) ) sqlite3BtreeRollback(p);
6383 6389
6384 /* Start an exclusive transaction. This will check the headers, so 6390 /* Start an exclusive transaction. This will check the headers, so
6385 ** if someone else poisoned the database we should get an error. 6391 ** if someone else poisoned the database we should get an error.
6386 */ 6392 */
6387 rc = sqlite3BtreeBeginTrans(p, 2); 6393 rc = sqlite3BtreeBeginTrans(p, 2);
6388 /* TODO(shess): Handle SQLITE_BUSY? */ 6394 /* TODO(shess): Handle SQLITE_BUSY? */
6389 if( rc!=SQLITE_OK ) return rc; 6395 if( rc!=SQLITE_OK ) return rc;
6390 6396
6391 /* Copied from sqlite3BtreeUpdateMeta(). Writing the old version of 6397 /* Copied from sqlite3BtreeUpdateMeta(). Writing the old version of
6392 ** the page to the journal may be overkill, but it probably won't 6398 ** the page to the journal may be overkill, but it probably won't
6393 ** hurt. 6399 ** hurt.
6394 */ 6400 */
6395 assert( pBt->inTrans==TRANS_WRITE ); 6401 assert( pBt->inTrans==TRANS_WRITE );
6396 assert( pBt->pPage1!=0 ); 6402 assert( pBt->pPage1!=0 );
6397 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); 6403 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
6398 if( rc ) goto err; 6404 if( rc ) goto err;
6399 6405
6400 /* "SQLite format 3" changes to 6406 /* "SQLite format 3" changes to
6401 ** "SQLite poison 3". Be extra paranoid about making this change. 6407 ** "SQLite poison 3". Be extra paranoid about making this change.
6402 */ 6408 */
6403 if( sizeof(zMagicHeader)!=16 || 6409 if( sizeof(zMagicHeader)!=16 ||
6404 sizeof(zPoisonHeader)!=sizeof(zMagicHeader) ){ 6410 sizeof(zPoisonHeader)!=sizeof(zMagicHeader) ){
6405 rc = SQLITE_ERROR; 6411 rc = SQLITE_ERROR;
6406 goto err; 6412 goto err;
6407 } 6413 }
6408 pP1 = pBt->pPage1->aData; 6414 pP1 = pBt->pPage1->aData;
6409 if( memcmp(pP1, zMagicHeader, 16)!=0 ){ 6415 if( memcmp(pP1, zMagicHeader, 16)!=0 ){
6410 rc = SQLITE_CORRUPT; 6416 rc = SQLITE_CORRUPT;
6411 goto err; 6417 goto err;
6412 } 6418 }
6413 memcpy(pP1, zPoisonHeader, 16); 6419 memcpy(pP1, zPoisonHeader, 16);
6414 6420
6415 /* Push it to the database file. */ 6421 /* Push it to the database file. */
6416 return sqlite3BtreeCommit(p); 6422 return sqlite3BtreeCommit(p);
6417 6423
6418 err: 6424 err:
6419 /* TODO(shess): What about errors, here? */ 6425 /* TODO(shess): What about errors, here? */
6420 sqlite3BtreeRollback(p); 6426 sqlite3BtreeRollback(p);
6421 return rc; 6427 return rc;
6422 } 6428 }
6423 6429
6424 #endif 6430 #endif
6431
6432 int sqlite3_get_user_version(sqlite3 *sqlite, int *user_version) {
6433 Btree *bt;
6434
6435 if( sqlite == NULL ) return SQLITE_ERROR;
6436 if( sqlite->nDb<1 ) return SQLITE_ERROR;
6437
6438 /* grab actual (not temporary tables) database */
Scott.Hess 2008/05/22 23:44:28 Comments should mostly be composed of sentences.
Dimitri 2008/06/04 03:02:16 On 2008/05/22 23:44:28, Scott.Hess wrote: > Commen
6439 bt = sqlite->aDb[0].pBt;
6440 /* because sqlite3BtreeGetMeta sets a table read lock, it is safe to use
6441 ** without explicit read transaction. Besides, it is very unlikely we will
6442 ** ever call this outside of a transaction.
6443 */
6444 return sqlite3BtreeGetMeta(bt, kUserCookie, (u32 *)user_version);
6445 }
6446
6447 int sqlite3_set_user_version(sqlite3 *sqlite, int user_version) {
6448 Btree *bt;
6449 int rc;
6450
6451 if( sqlite == NULL ) return SQLITE_ERROR;
6452 if( sqlite->nDb<1 ) return SQLITE_ERROR;
6453
6454 bt = sqlite->aDb[0].pBt;
6455 if( bt->inTrans!= TRANS_WRITE ) {
Scott.Hess 2008/05/22 23:44:28 Shouldn't this be ==? No space after = sign in an
Dimitri 2008/06/04 03:02:16 On 2008/05/22 23:44:28, Scott.Hess wrote: > Should
6456 return sqlite3BtreeUpdateMeta(bt, kUserCookie, (u32)user_version);
6457 }else{
6458 /* transacion isn't already in progress, have to enclose in
6459 ** a write-transaction
6460 */
Scott.Hess 2008/05/22 23:44:28 sp on first occurrence of transaction. Revise com
6461 rc = sqlite3BtreeBeginTrans(bt, 1);
6462 if( rc!=SQLITE_OK ) return rc;
6463 rc = sqlite3BtreeUpdateMeta(bt, kUserCookie, (u32)user_version);
6464 if( rc==SQLITE_OK ) return sqlite3BtreeCommit(bt);
6465 sqlite3BtreeRollback(bt);
6466 return rc;
Scott.Hess 2008/05/22 23:44:28 For Database2, is it even possible to get to this
Dimitri 2008/06/04 03:02:16 On 2008/05/22 23:44:28, Scott.Hess wrote: > For Da
6467 }
6468 }
Scott.Hess 2008/05/22 23:44:28 Sorry to be a pain, I'm trying to recall why we're
Dimitri 2008/06/04 03:02:16 On 2008/05/22 23:44:28, Scott.Hess wrote: > Sorry
OLDNEW

Powered by Google App Engine
This is Rietveld r305