]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update the file change counter just before each transaction is committed. (CVS 1582)
authordanielk1977 <danielk1977@noemail.net>
Mon, 14 Jun 2004 05:10:42 +0000 (05:10 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 14 Jun 2004 05:10:42 +0000 (05:10 +0000)
FossilOrigin-Name: 4649abcbfd032836b196b5d690ef66e4aa494c45

manifest
manifest.uuid
src/pager.c
src/vdbe.c

index 045040dcd4000c8df4d7b0cdd130e782bba3d09a..0e6418374d895400769ef2af49191ecd41f7ace9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C os_win.c\sis\snow\sworking\swith\sthe\snew\slocking\sprotocol.\s(CVS\s1581)
-D 2004-06-13T23:07:04
+C Update\sthe\sfile\schange\scounter\sjust\sbefore\seach\stransaction\sis\scommitted.\s(CVS\s1582)
+D 2004-06-14T05:10:43
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -48,7 +48,7 @@ F src/os_unix.c 7ece785e36c4ecb57c73db8d374b56912d742c4a
 F src/os_unix.h 1cd6133cf66dea704b8646b70b2dfdcbdd9b3738
 F src/os_win.c d4009586dfd0543ca8956ff0be30f9d23e2cbbdd
 F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c
-F src/pager.c 4a2d3c871169385f7fe65c37919ced82cb3d34ed
+F src/pager.c feb44bd0279f77319079c1fddf9be927b052d028
 F src/pager.h ca8f293e1d623a7c628a1c5e0c6cf43d5bbb80bf
 F src/parse.y 097438674976355a10cf177bd97326c548820b86
 F src/pragma.c e288bd122d3ca41ec2032475abde1ff5fa3095f4
@@ -71,7 +71,7 @@ F src/update.c 6133c876aa126e1771cda165fd992bb0d2f8eb38
 F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76
 F src/util.c 90375fa253137562d536ccdd40b297f0fd7413fc
 F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
-F src/vdbe.c c71e47262d3d3539a20a489a03b9cde15ef3acb7
+F src/vdbe.c e6b6702fb2c2e2702e312f52c2cc08353c580736
 F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
 F src/vdbeInt.h ffc7b8ed911c5bf804796a768fdb6f0568010fa2
 F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829
@@ -223,7 +223,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
 F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P c5ebc1c05eccc2c0697b6047a504954e11960f73
-R 4b53e920198647f93177549edf4e8baf
-U drh
-Z 362250ddf90f1c6b39b6cc80b805170c
+P 77c5eaa10a9d2e2bb8f89b7434d6e6efbacf35e9
+R 728fa94fee79e66b965ca32e2cd56d1b
+U danielk1977
+Z 982942d9d284a3b9c20e3e9aaf713011
index 809d329572a65570b6605702a49434fa845d4610..8aed1a27f6019c47ea2c071452c0d05fed925714 100644 (file)
@@ -1 +1 @@
-77c5eaa10a9d2e2bb8f89b7434d6e6efbacf35e9
\ No newline at end of file
+4649abcbfd032836b196b5d690ef66e4aa494c45
\ No newline at end of file
index add2e80b465907a45724c655daff9bb2428adb8c..94f9954466639a83f2b80d93eff2225d63896266 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.124 2004/06/12 01:43:26 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.125 2004/06/14 05:10:43 danielk1977 Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -71,6 +71,13 @@ static Pager *mainPager = 0;
 **                       threads can be reading or writing while one
 **                       process is writing.
 **
+**   PAGER_SYNCED        The pager moves to this state from PAGER_EXCLUSIVE
+**                       after all dirty pages have been written to the
+**                       database file and the file has been synced to
+**                       disk. All that remains to do is to remove the
+**                       journal file and the transaction will be
+**                       committed.
+**
 ** The page cache comes up in PAGER_UNLOCK.  The first time a
 ** sqlite3pager_get() occurs, the state transitions to PAGER_SHARED.
 ** After all pages have been released using sqlite_page_unref(),
@@ -87,6 +94,7 @@ static Pager *mainPager = 0;
 #define PAGER_SHARED      1
 #define PAGER_RESERVED    2
 #define PAGER_EXCLUSIVE   3
+#define PAGER_SYNCED      4
 
 
 /*
@@ -323,8 +331,8 @@ static int write32bits(OsFile *fd, u32 val){
 }
 
 /*
-** Write a 32-bit integer into a page header right before the
-** page data.  This will overwrite the PgHdr.pDirty pointer.
+** Write the 32-bit integer 'val' into the page identified by page header
+** 'p' at offset 'offset'.
 */
 static void store32bits(u32 val, PgHdr *p, int offset){
   unsigned char *ac;
@@ -335,6 +343,16 @@ static void store32bits(u32 val, PgHdr *p, int offset){
   ac[3] = val & 0xff;
 }
 
+/*
+** Read a 32-bit integer at offset 'offset' from the page identified by
+** page header 'p'.
+*/
+static u32 retrieve32bits(PgHdr *p, int offset){
+  unsigned char *ac;
+  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
+  return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
+}
+
 
 /*
 ** Convert the bits in the pPager->errMask into an approprate
@@ -532,7 +550,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
     }
   }
 
-  assert( pPager->state==PAGER_RESERVED || pPager->state==PAGER_EXCLUSIVE );
+  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
 
   /* If the pager is in RESERVED state, then there must be a copy of this
   ** page in the pager cache. In this case just update the pager cache,
@@ -546,9 +564,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   ** and the main file. The page is then marked not dirty.
   */
   pPg = pager_lookup(pPager, pgno);
-  assert( pPager->state==PAGER_EXCLUSIVE || pPg );
+  assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
   TRACE2("PLAYBACK page %d\n", pgno);
-  if( pPager->state==PAGER_EXCLUSIVE ){
+  if( pPager->state>=PAGER_EXCLUSIVE ){
     sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
     rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE);
   }
@@ -564,7 +582,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
     if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
       pPager->xDestructor(pData, pPager->pageSize);
     }
-    if( pPager->state==PAGER_EXCLUSIVE ){
+    if( pPager->state>=PAGER_EXCLUSIVE ){
       pPg->dirty = 0;
       pPg->needSync = 0;
     }
@@ -1315,6 +1333,7 @@ int sqlite3pager_close(Pager *pPager){
   PgHdr *pPg, *pNext;
   switch( pPager->state ){
     case PAGER_RESERVED:
+    case PAGER_SYNCED: 
     case PAGER_EXCLUSIVE: {
       sqlite3pager_rollback(pPager);
       if( !pPager->memDb ){
@@ -2627,6 +2646,35 @@ void sqlite3pager_set_codec(
   pPager->pCodecArg = pCodecArg;
 }
 
+/*
+** This routine is called to increment the database file change-counter,
+** stored at byte 24 of the pager file.
+*/
+static int pager_incr_changecounter(Pager *pPager){
+  void *pPage;
+  PgHdr *pPgHdr;
+  u32 change_counter;
+  int rc;
+
+  /* Open page 1 of the file for writing. */
+  rc = sqlite3pager_get(pPager, 1, &pPage);
+  if( rc!=SQLITE_OK ) return rc;
+  rc = sqlite3pager_write(pPage);
+  if( rc!=SQLITE_OK ) return rc;
+
+  /* Read the current value at byte 24. */
+  pPgHdr = DATA_TO_PGHDR(pPage);
+  change_counter = retrieve32bits(pPgHdr, 24);
+
+  /* Increment the value just read and write it back to byte 24. */
+  change_counter++;
+  store32bits(change_counter, pPgHdr, 24);
+
+  /* Release the page reference. */
+  sqlite3pager_unref(pPage);
+  return SQLITE_OK;
+}
+
 /*
 ** Sync the database file for the pager pPager. zMaster points to the name
 ** of a master journal file that should be written into the individual
@@ -2644,13 +2692,16 @@ void sqlite3pager_set_codec(
 int sqlite3pager_sync(Pager *pPager, const char *zMaster){
   int rc = SQLITE_OK;
 
-  /* If this is an in-memory db, or no pages have been written to, this
-  ** function is a no-op.
+  /* If this is an in-memory db, or no pages have been written to, or this
+  ** function has already been called, it is a no-op.
   */
-  if( !pPager->memDb && pPager->dirtyCache ){
+  if( pPager->state!=PAGER_SYNCED && !pPager->memDb && pPager->dirtyCache ){
     PgHdr *pPg;
     assert( pPager->journalOpen );
 
+    rc = pager_incr_changecounter(pPager);
+    if( rc!=SQLITE_OK ) goto sync_exit;
+
     /* Sync the journal file */
     rc = syncJournal(pPager, zMaster);
     if( rc!=SQLITE_OK ) goto sync_exit;
@@ -2660,10 +2711,12 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster){
     rc = pager_write_pagelist(pPg);
     if( rc!=SQLITE_OK ) goto sync_exit;
 
-    /* If any pages were actually written, sync the database file */
-    if( pPg && !pPager->noSync ){
+    /* Sync the database file. */
+    if( !pPager->noSync ){
       rc = sqlite3OsSync(&pPager->fd);
     }
+
+    pPager->state = PAGER_SYNCED;
   }
 
 sync_exit:
index 9057e0de4ec44fbe20a6e45e7f5624cb36b1782a..9cba2007762d32be9ed8aac9c9698496f35e4a5d 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.370 2004/06/12 20:12:51 drh Exp $
+** $Id: vdbe.c,v 1.371 2004/06/14 05:10:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2136,7 +2136,7 @@ case OP_Column: {
 **  't'            TEXT
 **  'o'            NONE
 **
-** If P3 is NULL then datatype coercion occurs.
+** If P3 is NULL then no datatype coercion occurs.
 */
 /* Opcode MakeRecord P1 * P3
 **