engine/sqlite/src/pager.cpp
author Sebastian Brannstrom <sebastianb@symbian.org>
Fri, 22 Oct 2010 14:28:27 +0100
branchsymbian1
changeset 266 ff6cd24e77e2
parent 2 29cda98b007e
permissions -rw-r--r--
Slightly tweaked icons
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2001 September 15
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This is the implementation of the page cache subsystem or "pager".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
** The pager is used to access a database disk file.  It implements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** atomic commit and rollback through the use of a journal file that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** is separate from the database file.  The pager also implements file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
** locking to prevent two processes from writing the same database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
** file simultaneously, or one process from reading the database while
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
** another is writing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** @(#) $Id: pager.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
#ifndef SQLITE_OMIT_DISKIO
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
#include <assert.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
#include <string.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** Macros for troubleshooting.  Normally turned off
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
#if 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
#define sqlite3DebugPrintf printf
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
#define PAGERTRACE1(X)       sqlite3DebugPrintf(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
#define PAGERTRACE2(X,Y)     sqlite3DebugPrintf(X,Y)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
#define PAGERTRACE3(X,Y,Z)   sqlite3DebugPrintf(X,Y,Z)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
#define PAGERTRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
#define PAGERTRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
#define PAGERTRACE1(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
#define PAGERTRACE2(X,Y)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
#define PAGERTRACE3(X,Y,Z)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
#define PAGERTRACE4(X,Y,Z,W)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
#define PAGERTRACE5(X,Y,Z,W,V)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
** The following two macros are used within the PAGERTRACEX() macros above
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
** to print out file-descriptors. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
** PAGERID() takes a pointer to a Pager struct as its argument. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
** struct as its argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
#define PAGERID(p) ((int)(p->fd))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
#define FILEHANDLEID(fd) ((int)fd)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
** The page cache as a whole is always in one of the following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
** states:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
**   PAGER_UNLOCK        The page cache is not currently reading or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
**                       writing the database file.  There is no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
**                       data held in memory.  This is the initial
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
**                       state.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
**   PAGER_SHARED        The page cache is reading the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
**                       Writing is not permitted.  There can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
**                       multiple readers accessing the same database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
**                       file at the same time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
**   PAGER_RESERVED      This process has reserved the database for writing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
**                       but has not yet made any changes.  Only one process
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
**                       at a time can reserve the database.  The original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
**                       database file has not been modified so other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
**                       processes may still be reading the on-disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
**                       database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
**   PAGER_EXCLUSIVE     The page cache is writing the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
**                       Access is exclusive.  No other processes or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
**                       threads can be reading or writing while one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
**                       process is writing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
**   PAGER_SYNCED        The pager moves to this state from PAGER_EXCLUSIVE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
**                       after all dirty pages have been written to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
**                       database file and the file has been synced to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
**                       disk. All that remains to do is to remove or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
**                       truncate the journal file and the transaction 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
**                       will be committed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
** The page cache comes up in PAGER_UNLOCK.  The first time a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** After all pages have been released using sqlite_page_unref(),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** the state transitions back to PAGER_UNLOCK.  The first time
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
** that sqlite3PagerWrite() is called, the state transitions to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
** PAGER_RESERVED.  (Note that sqlite3PagerWrite() can only be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
** called on an outstanding page which means that the pager must
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
** PAGER_RESERVED means that there is an open rollback journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
** The transition to PAGER_EXCLUSIVE occurs before any changes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
** are made to the database file, though writes to the rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
** journal occurs with just PAGER_RESERVED.  After an sqlite3PagerRollback()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
#define PAGER_UNLOCK      0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
#define PAGER_SHARED      1   /* same as SHARED_LOCK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
#define PAGER_RESERVED    2   /* same as RESERVED_LOCK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
#define PAGER_EXCLUSIVE   4   /* same as EXCLUSIVE_LOCK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
#define PAGER_SYNCED      5
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
** If the SQLITE_BUSY_RESERVED_LOCK macro is set to true at compile-time,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
** then failed attempts to get a reserved lock will invoke the busy callback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
** This is off by default.  To see why, consider the following scenario:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
** Suppose thread A already has a shared lock and wants a reserved lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
** Thread B already has a reserved lock and wants an exclusive lock.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
** both threads are using their busy callbacks, it might be a long time
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
** be for one of the threads give up and allows the other to proceed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
** But if the thread trying to get the reserved lock gives up quickly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
** (if it never invokes its busy callback) then the contention will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
** resolved quickly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
#ifndef SQLITE_BUSY_RESERVED_LOCK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
# define SQLITE_BUSY_RESERVED_LOCK 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
** This macro rounds values up so that if the value is an address it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
** is guaranteed to be an address that is aligned to an 8-byte boundary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
#define FORCE_ALIGNMENT(X)   (((X)+7)&~7)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
typedef struct PgHdr PgHdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
** Each pager stores all currently unreferenced pages in a list sorted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
** in least-recently-used (LRU) order (i.e. the first item on the list has 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
** not been referenced in a long time, the last item has been recently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
** used). An instance of this structure is included as part of each
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
** pager structure for this purpose (variable Pager.lru).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
** Additionally, if memory-management is enabled, all unreferenced pages 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
** are stored in a global LRU list (global variable sqlite3LruPageList).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
** In both cases, the PagerLruList.pFirstSynced variable points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
** the first page in the corresponding list that does not require an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
** fsync() operation before its memory can be reclaimed. If no such
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
** page exists, PagerLruList.pFirstSynced is set to NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
typedef struct PagerLruList PagerLruList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
struct PagerLruList {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  PgHdr *pFirst;         /* First page in LRU list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  PgHdr *pLast;          /* Last page in LRU list (the most recently used) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
  PgHdr *pFirstSynced;   /* First page in list with PgHdr.needSync==0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
** The following structure contains the next and previous pointers used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
** to link a PgHdr structure into a PagerLruList linked list. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
typedef struct PagerLruLink PagerLruLink;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
struct PagerLruLink {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  PgHdr *pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  PgHdr *pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
** Each in-memory image of a page begins with the following header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
** This header is only visible to this pager module.  The client
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
** code that calls pager sees only the data that follows the header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
** Client code should call sqlite3PagerWrite() on a page prior to making
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
** any modifications to that page.  The first time sqlite3PagerWrite()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
** is called, the original page contents are written into the rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
** journal and PgHdr.inJournal and PgHdr.needSync are set.  Later, once
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
** the journal page has made it onto the disk surface, PgHdr.needSync
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
** is cleared.  The modified page cannot be written back into the original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
** database file until the journal pages has been synced to disk and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
** PgHdr.needSync has been cleared.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
** The PgHdr.dirty flag is set when sqlite3PagerWrite() is called and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
** is cleared again when the page content is written back to the original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
** database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
** Details of important structure elements:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
** needSync
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
**     If this is true, this means that it is not safe to write the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
**     content to the database because the original content needed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
**     for rollback has not by synced to the main rollback journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
**     The original content may have been written to the rollback journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
**     but it has not yet been synced.  So we cannot write to the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
**     file because power failure might cause the page in the journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
**     to never reach the disk.  It is as if the write to the journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
**     does not occur until the journal file is synced.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
**     
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
**     This flag is false if the page content exactly matches what
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
**     currently exists in the database file.  The needSync flag is also
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
**     false if the original content has been written to the main rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
**     journal and synced.  If the page represents a new page that has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
**     been added onto the end of the database during the current
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
**     transaction, the needSync flag is true until the original database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
**     size in the journal header has been synced to disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
** inJournal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
**     This is true if the original page has been written into the main
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
**     rollback journal.  This is always false for new pages added to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
**     the end of the database file during the current transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
**     And this flag says nothing about whether or not the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
**     has been synced to disk.  For pages that are in the original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
**     database file, the following expression should always be true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
**       inJournal = (pPager->aInJournal[(pgno-1)/8] & (1<<((pgno-1)%8))!=0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
**     The pPager->aInJournal[] array is only valid for the original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
**     pages of the database, not new pages that are added to the end
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
**     of the database, so obviously the above expression cannot be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
**     valid for new pages.  For new pages inJournal is always 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
** dirty
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
**     When true, this means that the content of the page has been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
**     modified and needs to be written back to the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
**     If false, it means that either the content of the page is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
**     unchanged or else the content is unimportant and we do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
**     care whether or not it is preserved.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
** alwaysRollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
**     This means that the sqlite3PagerDontRollback() API should be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
**     ignored for this page.  The DontRollback() API attempts to say
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
**     that the content of the page on disk is unimportant (it is an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
**     unused page on the freelist) so that it is unnecessary to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
**     rollback changes to this page because the content of the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
**     can change without changing the meaning of the database.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
**     flag overrides any DontRollback() attempt.  This flag is set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
**     when a page that originally contained valid data is added to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
**     the freelist.  Later in the same transaction, this page might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
**     be pulled from the freelist and reused for something different
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
**     and at that point the DontRollback() API will be called because
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
**     pages taken from the freelist do not need to be protected by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
**     the rollback journal.  But this flag says that the page was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
**     not originally part of the freelist so that it still needs to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
**     be rolled back in spite of any subsequent DontRollback() calls.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
** needRead 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
**     This flag means (when true) that the content of the page has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
**     not yet been loaded from disk.  The in-memory content is just
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
**     garbage.  (Actually, we zero the content, but you should not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
**     make any assumptions about the content nevertheless.)  If the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
**     content is needed in the future, it should be read from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
**     original database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
struct PgHdr {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  Pager *pPager;                 /* The pager to which this page belongs */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  Pgno pgno;                     /* The page number for this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  PgHdr *pNextHash, *pPrevHash;  /* Hash collision chain for PgHdr.pgno */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  PagerLruLink free;             /* Next and previous free pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  PgHdr *pNextAll;               /* A list of all pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  u8 inJournal;                  /* TRUE if has been written to journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
  u8 dirty;                      /* TRUE if we need to write back changes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
  u8 needSync;                   /* Sync journal before writing this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
  u8 alwaysRollback;             /* Disable DontRollback() for this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
  u8 needRead;                   /* Read content if PagerWrite() is called */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
  short int nRef;                /* Number of users of this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
  PgHdr *pDirty, *pPrevDirty;    /* Dirty pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
  PagerLruLink gfree;            /* Global list of nRef==0 pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  u32 pageHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  void *pData;                   /* Page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  /* Pager.nExtra bytes of local data appended to this header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
** For an in-memory only database, some extra information is recorded about
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
** each page so that changes can be rolled back.  (Journal files are not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
** used for in-memory databases.)  The following information is added to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
** the end of every EXTRA block for in-memory databases.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
** This information could have been added directly to the PgHdr structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
** But then it would take up an extra 8 bytes of storage on every PgHdr
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
** even for disk-based databases.  Splitting it out saves 8 bytes.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
** is only a savings of 0.8% but those percentages add up.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
typedef struct PgHistory PgHistory;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
struct PgHistory {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
  u8 *pOrig;     /* Original page text.  Restore to this on a full rollback */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  u8 *pStmt;     /* Text as it was at the beginning of the current statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  PgHdr *pNextStmt, *pPrevStmt;  /* List of pages in the statement journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
  u8 inStmt;                     /* TRUE if in the statement subjournal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
** A macro used for invoking the codec if there is one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
#ifdef SQLITE_HAS_CODEC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
# define CODEC1(P,D,N,X) /* NO-OP */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
# define CODEC2(P,D,N,X) ((char*)D)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
** Convert a pointer to a PgHdr into a pointer to its data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
** and back again.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
#define PGHDR_TO_DATA(P)    ((P)->pData)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
#define PGHDR_TO_EXTRA(G,P) ((void*)&((G)[1]))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
#define PGHDR_TO_HIST(P,PGR)  \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
            ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->nExtra])
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
** A open page cache is an instance of the following structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
** or SQLITE_FULL. Once one of the first three errors occurs, it persists
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
** and is returned as the result of every major pager API call.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
** SQLITE_FULL return code is slightly different. It persists only until the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
** next successful rollback is performed on the pager cache. Also,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
** APIs, they may still be used successfully.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
struct Pager {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
  u8 journalOpen;             /* True if journal file descriptors is valid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
  u8 journalStarted;          /* True if header of journal is synced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
  u8 useJournal;              /* Use a rollback journal on this file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
  u8 noReadlock;              /* Do not bother to obtain readlocks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
  u8 stmtOpen;                /* True if the statement subjournal is open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
  u8 stmtInUse;               /* True we are in a statement subtransaction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
  u8 noSync;                  /* Do not sync the journal if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  u8 sync_flags;              /* One of SYNC_NORMAL or SYNC_FULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
  u8 tempFile;                /* zFilename is a temporary file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
  u8 readOnly;                /* True for a read-only database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
  u8 needSync;                /* True if an fsync() is needed on the journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
  u8 dirtyCache;              /* True if cached pages have changed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
  u8 memDb;                   /* True to inhibit all file I/O */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
  u8 changeCountDone;         /* Set after incrementing the change-counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
  int errCode;                /* One of several kinds of errors */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
  int dbSize;                 /* Number of pages in the file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
  int origDbSize;             /* dbSize before the current change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
  int nRec;                   /* Number of pages written to the journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
  u32 cksumInit;              /* Quasi-random value added to every checksum */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
  int stmtNRec;               /* Number of records in stmt subjournal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
  int nExtra;                 /* Add this many bytes to each in-memory page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
  int pageSize;               /* Number of bytes in a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  int nPage;                  /* Total number of in-memory pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  int mxPage;                 /* Maximum number of pages to hold in cache */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
  Pgno mxPgno;                /* Maximum allowed size of the database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  u8 *aInJournal;             /* One bit for each page in the database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
  u8 *aInStmt;                /* One bit for each page in the database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
  char *zFilename;            /* Name of the database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
  char *zJournal;             /* Name of the journal file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
  char *zDirectory;           /* Directory hold database and journal files */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
  char *zStmtJrnl;            /* Name of the statement journal file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
  sqlite3_file *fd, *jfd;     /* File descriptors for database and journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
  sqlite3_file *stfd;         /* File descriptor for the statement subjournal*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
  BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
  PagerLruList lru;           /* LRU list of free pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
  PgHdr *pAll;                /* List of all pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
  PgHdr *pStmt;               /* List of pages in the statement subjournal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
  PgHdr *pDirty;              /* List of all dirty pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
  i64 journalOff;             /* Current byte offset in the journal file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
  i64 journalHdr;             /* Byte offset to previous journal header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
  i64 stmtHdrOff;             /* First journal header written this statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
  i64 stmtCksum;              /* cksumInit when statement was started */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
  i64 stmtJSize;              /* Size of journal at stmt_begin() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
  int sectorSize;             /* Assumed sector size during rollback */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
  int nHit, nMiss;            /* Cache hits and missing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
  int nRead, nWrite;          /* Database pages read/written */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  void (*xDestructor)(DbPage*,int); /* Call this routine when freeing pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  void (*xReiniter)(DbPage*,int);   /* Call this routine when reloading pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
#ifdef SQLITE_HAS_CODEC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  void *pCodecArg;            /* First argument to xCodec() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  int nHash;                  /* Size of the pager hash table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
  PgHdr **aHash;              /* Hash table to map page number to PgHdr */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
  Pager *pNext;               /* Doubly linked list of pagers on which */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
  Pager *pPrev;               /* sqlite3_release_memory() will work */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  int iInUseMM;               /* Non-zero if unavailable to MM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  int iInUseDB;               /* Non-zero if in sqlite3_release_memory() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
  char dbFileVers[16];        /* Changes whenever database file changes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
** The following global variables hold counters used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
** testing purposes only.  These variables do not exist in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
** a non-testing build.  These variables are not thread-safe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
int sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
int sqlite3_pager_pgfree_count = 0;    /* Number of cache pages freed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
# define PAGER_INCR(v)  v++
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
# define PAGER_INCR(v)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
** The following variable points to the head of a double-linked list
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
** of all pagers that are eligible for page stealing by the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
** sqlite3_release_memory() interface.  Access to this list is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
** protected by the SQLITE_MUTEX_STATIC_MEM2 mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
static Pager *sqlite3PagerList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
static PagerLruList sqlite3LruPageList = {0, 0, 0};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
** Journal files begin with the following magic string.  The data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
** was obtained from /dev/random.  It is used only as a sanity check.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
** Since version 2.8.0, the journal format contains additional sanity
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
** checking information.  If the power fails while the journal is begin
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
** written, semi-random garbage data might appear in the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
** file after power is restored.  If an attempt is then made
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
** to roll the journal back, the database could be corrupted.  The additional
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
** sanity checking data is an attempt to discover the garbage in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
** journal and ignore it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** The sanity checking information for the new journal format consists
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
** of a 32-bit checksum on each page of data.  The checksum covers both
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
** the page number and the pPager->pageSize bytes of data for the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
** This cksum is initialized to a 32-bit random value that appears in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
** journal file right after the header.  The random initializer is important,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
** because garbage data that appears at the end of a journal is likely
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
** data that was once in other files that have now been deleted.  If the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
** garbage data came from an obsolete journal file, the checksums might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
** be correct.  But by initializing the checksum to random value which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
** is different for every journal, we minimize that risk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
static const unsigned char aJournalMagic[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
** The size of the header and of each page in the journal is determined
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
** by the following macros.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
** The journal header size for this pager. In the future, this could be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
** set to some value read from the disk controller. The important
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
** characteristic is that it is the same size as a disk sector.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
** The macro MEMDB is true if we are dealing with an in-memory database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
** the value of MEMDB will be a constant and the compiler will optimize
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
** out code that would never execute.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
#ifdef SQLITE_OMIT_MEMORYDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
# define MEMDB 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
# define MEMDB pPager->memDb
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
** reserved for working around a windows/posix incompatibility). It is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
** used in the journal to signify that the remainder of the journal file 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
** is devoted to storing a master journal name - there are no more pages to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
** roll back. See comments for function writeMasterJournal() for details.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
** The maximum legal page number is (2^31 - 1).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
#define PAGER_MAX_PGNO 2147483647
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
** The pagerEnter() and pagerLeave() routines acquire and release
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
** a mutex on each pager.  The mutex is recursive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
** This is a special-purpose mutex.  It only provides mutual exclusion
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
** between the Btree and the Memory Management sqlite3_release_memory()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
** function.  It does not prevent, for example, two Btrees from accessing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
** the same pager at the same time.  Other general-purpose mutexes in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
** the btree layer handle that chore.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  static void pagerEnter(Pager *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
    p->iInUseDB++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
    if( p->iInUseMM && p->iInUseDB==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
      sqlite3_mutex *mutex;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
      p->iInUseDB = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
      sqlite3_mutex_enter(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
      p->iInUseDB = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
      sqlite3_mutex_leave(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
    assert( p->iInUseMM==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
  static void pagerLeave(Pager *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
    p->iInUseDB--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
    assert( p->iInUseDB>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
# define pagerEnter(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
# define pagerLeave(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
** Enable reference count tracking (for debugging) here:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  int pager3_refinfo_enable = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  static void pager_refinfo(PgHdr *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
    static int cnt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
    if( !pager3_refinfo_enable ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
    sqlite3DebugPrintf(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
       "REFCNT: %4d addr=%p nRef=%-3d total=%d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
       p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
    cnt++;   /* Something to set a breakpoint on */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
# define REFINFO(X)  pager_refinfo(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
# define REFINFO(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
** Add page pPg to the end of the linked list managed by structure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
** pList (pPg becomes the last entry in the list - the most recently 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
** used). Argument pLink should point to either pPg->free or pPg->gfree,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
** depending on whether pPg is being added to the pager-specific or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
** global LRU list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
static void listAdd(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  pLink->pNext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
  pLink->pPrev = pList->pLast;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
  assert(pLink==&pPg->free || pLink==&pPg->gfree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
  assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
  if( pList->pLast ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
    int iOff = (char *)pLink - (char *)pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
    PagerLruLink *pLastLink = (PagerLruLink *)(&((u8 *)pList->pLast)[iOff]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
    pLastLink->pNext = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
    assert(!pList->pFirst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    pList->pFirst = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
  pList->pLast = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
  if( !pList->pFirstSynced && pPg->needSync==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    pList->pFirstSynced = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
** Remove pPg from the list managed by the structure pointed to by pList.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
** Argument pLink should point to either pPg->free or pPg->gfree, depending 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
** on whether pPg is being added to the pager-specific or global LRU list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
static void listRemove(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  int iOff = (char *)pLink - (char *)pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
  assert(pLink==&pPg->free || pLink==&pPg->gfree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  if( pPg==pList->pFirst ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
    pList->pFirst = pLink->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
  if( pPg==pList->pLast ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
    pList->pLast = pLink->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
  if( pLink->pPrev ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
    PagerLruLink *pPrevLink = (PagerLruLink *)(&((u8 *)pLink->pPrev)[iOff]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
    pPrevLink->pNext = pLink->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
  if( pLink->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
    PagerLruLink *pNextLink = (PagerLruLink *)(&((u8 *)pLink->pNext)[iOff]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
    pNextLink->pPrev = pLink->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
  if( pPg==pList->pFirstSynced ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
    PgHdr *p = pLink->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
    while( p && p->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
      PagerLruLink *pL = (PagerLruLink *)(&((u8 *)p)[iOff]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
      p = pL->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
    pList->pFirstSynced = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
  pLink->pNext = pLink->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
** Add page pPg to the list of free pages for the pager. If 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
** memory-management is enabled, also add the page to the global 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
** list of free pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
static void lruListAdd(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
  listAdd(&pPg->pPager->lru, &pPg->free, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
  if( !pPg->pPager->memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
    listAdd(&sqlite3LruPageList, &pPg->gfree, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
** Remove page pPg from the list of free pages for the associated pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
** If memory-management is enabled, also remove pPg from the global list
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
** of free pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
static void lruListRemove(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
  listRemove(&pPg->pPager->lru, &pPg->free, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
  if( !pPg->pPager->memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
    listRemove(&sqlite3LruPageList, &pPg->gfree, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
** This function is called just after the needSync flag has been cleared
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
** from all pages managed by pPager (usually because the journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
** has just been synced). It updates the pPager->lru.pFirstSynced variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
** and, if memory-management is enabled, the sqlite3LruPageList.pFirstSynced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
** variable also.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
static void lruListSetFirstSynced(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
  pPager->lru.pFirstSynced = pPager->lru.pFirst;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
  if( !pPager->memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
    PgHdr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
    for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
    assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
    sqlite3LruPageList.pFirstSynced = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
** Return true if page *pPg has already been written to the statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
** journal (or statement snapshot has been created, if *pPg is part
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
** of an in-memory database).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
static int pageInStatement(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
    return PGHDR_TO_HIST(pPg, pPager)->inStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
    Pgno pgno = pPg->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
    u8 *a = pPager->aInStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
    return (a && (int)pgno<=pPager->stmtSize && (a[pgno/8] & (1<<(pgno&7))));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
** Change the size of the pager hash table to N.  N must be a power
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
** of two.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
static void pager_resize_hash_table(Pager *pPager, int N){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
  PgHdr **aHash, *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
  assert( N>0 && (N&(N-1))==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
  sqlite3MallocBenignFailure((int)pPager->aHash);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
  aHash = (PgHdr**)sqlite3MallocZero( sizeof(aHash[0])*N );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
  if( aHash==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
    /* Failure to rehash is not an error.  It is only a performance hit. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
  sqlite3_free(pPager->aHash);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
  pPager->nHash = N;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
  pPager->aHash = aHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
    int h;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
    if( pPg->pgno==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
      assert( pPg->pNextHash==0 && pPg->pPrevHash==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
      continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
    h = pPg->pgno & (N-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
    pPg->pNextHash = aHash[h];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
    if( aHash[h] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
      aHash[h]->pPrevHash = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
    aHash[h] = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
    pPg->pPrevHash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
** Read a 32-bit integer from the given file descriptor.  Store the integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
** error code is something goes wrong.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
** All values are stored on disk as big-endian.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
  unsigned char ac[4];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
    *pRes = sqlite3Get4byte(ac);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
** Write a 32-bit integer into a string buffer in big-endian byte order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
** on success or an error code is something goes wrong.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
  char ac[4];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
  put32bits(ac, val);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
  return sqlite3OsWrite(fd, ac, 4, offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
** If file pFd is open, call sqlite3OsUnlock() on it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
static int osUnlock(sqlite3_file *pFd, int eLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
  if( !pFd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
  return sqlite3OsUnlock(pFd, eLock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
** This function determines whether or not the atomic-write optimization
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
** can be used with this pager. The optimization can be used if:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
**  (a) the value returned by OsDeviceCharacteristics() indicates that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
**      a database page may be written atomically, and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
**  (b) the value returned by OsSectorSize() is less than or equal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
**      to the page size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
** If the optimization cannot be used, 0 is returned. If it can be used,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
** then the value returned is the size of the journal file when it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
** contains rollback data for exactly one page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
static int jrnlBufferSize(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
  int dc;           /* Device characteristics */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
  int nSector;      /* Sector size */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  int nPage;        /* Page size */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
  sqlite3_file *fd = pPager->fd;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
  if( fd->pMethods ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
    dc = sqlite3OsDeviceCharacteristics(fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
    nSector = sqlite3OsSectorSize(fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
    nPage = pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
  assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
  assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
  if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage>>8))&&nSector<=nPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
    return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
** This function should be called when an error occurs within the pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
** code. The first argument is a pointer to the pager structure, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
** second the error-code about to be returned by a pager API function. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
** The value returned is a copy of the second argument to this function. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
** the error becomes persistent. Until the persisten error is cleared,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
** subsequent API calls on this Pager will immediately return the same 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
** error code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
** A persistent error indicates that the contents of the pager-cache 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
** cannot be trusted. This state can be cleared by completely discarding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
** the contents of the pager-cache. If a transaction was active when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
** the persistent error occured, then the rollback journal may need
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
** to be replayed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
static void pager_unlock(Pager *pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
static int pager_error(Pager *pPager, int rc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
  int rc2 = rc & 0xff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
  assert(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
       pPager->errCode==SQLITE_FULL ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
       pPager->errCode==SQLITE_OK ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
       (pPager->errCode & 0xff)==SQLITE_IOERR
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
  if(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
    rc2==SQLITE_FULL ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
    rc2==SQLITE_IOERR ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
    rc2==SQLITE_CORRUPT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
    pPager->errCode = rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
    if( pPager->state==PAGER_UNLOCK && pPager->nRef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
      /* If the pager is already unlocked, call pager_unlock() now to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
      ** clear the error state and ensure that the pager-cache is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
      ** completely empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
      pager_unlock(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
** on the cache using a hash function.  This is used for testing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
** and debugging only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
** Return a 32-bit hash of the page data for pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
static u32 pager_datahash(int nByte, unsigned char *pData){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  u32 hash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  for(i=0; i<nByte; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
    hash = (hash*1039) + pData[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
  return hash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
static u32 pager_pagehash(PgHdr *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
  return pager_datahash(pPage->pPager->pageSize, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
                        (unsigned char *)PGHDR_TO_DATA(pPage));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
** is defined, and NDEBUG is not defined, an assert() statement checks
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
** that the page is either dirty or still matches the calculated page-hash.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
#define CHECK_PAGE(x) checkPage(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
static void checkPage(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
  assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
      pPg->pageHash==pager_pagehash(pPg) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
#define pager_datahash(X,Y)  0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
#define pager_pagehash(X)  0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
#define CHECK_PAGE(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
** When this is called the journal file for pager pPager must be open.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
** The master journal file name is read from the end of the file and 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
** written into memory supplied by the caller. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
** zMaster must point to a buffer of at least nMaster bytes allocated by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
** enough space to write the master journal name). If the master journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
** name in the journal is longer than nMaster bytes (including a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
** nul-terminator), then this is handled as if no master journal name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
** were present in the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
** If no master journal file name is present zMaster[0] is set to 0 and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
** SQLITE_OK returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, int nMaster){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
  u32 len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
  i64 szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
  u32 cksum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
  unsigned char aMagic[8]; /* A buffer to hold the magic header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
  zMaster[0] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
  rc = sqlite3OsFileSize(pJrnl, &szJ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
  if( rc!=SQLITE_OK || szJ<16 ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
  rc = read32bits(pJrnl, szJ-16, &len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  if( len>=nMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
  rc = read32bits(pJrnl, szJ-12, &cksum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
  rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
  if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
  rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
  zMaster[len] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
  /* See if the checksum matches the master journal name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
  for(i=0; i<len; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
    cksum -= zMaster[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
   }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
  if( cksum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
    /* If the checksum doesn't add up, then one or more of the disk sectors
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
    ** containing the master journal filename is corrupted. This means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
    ** definitely roll back, so just return SQLITE_OK and report a (nul)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
    ** master-journal filename.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
    zMaster[0] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
** Seek the journal file descriptor to the next sector boundary where a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
** journal header may be read or written. Pager.journalOff is updated with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
** the new seek offset.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
** i.e for a sector size of 512:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
** Input Offset              Output Offset
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
** ---------------------------------------
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
** 0                         0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
** 512                       512
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
** 100                       512
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
** 2000                      2048
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
static void seekJournalHdr(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
  i64 offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
  i64 c = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
  if( c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  assert( offset>=c );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  pPager->journalOff = offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
** The journal file must be open when this routine is called. A journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
** current location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
** The format for the journal header is as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
** - 8 bytes: Magic identifying journal format.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
** - 4 bytes: Random number used for page hash.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
** - 4 bytes: Initial database page count.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
** - 4 bytes: Sector size used by the process that wrote this journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
static int writeJournalHdr(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
  char zHeader[sizeof(aJournalMagic)+16];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
  if( pPager->stmtHdrOff==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
    pPager->stmtHdrOff = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
  seekJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
  pPager->journalHdr = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
  memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
  /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
  ** Write the nRec Field - the number of page records that follow this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  ** journal header. Normally, zero is written to this value at this time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
  ** After the records are added to the journal (and the journal synced, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  ** if in full-sync mode), the zero is overwritten with the true number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  ** of records (see syncJournal()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
  ** reading the journal this value tells SQLite to assume that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  ** rest of the journal file contains valid page records. This assumption
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
  ** is dangerous, as if a failure occured whilst writing to the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  ** file it may contain some garbage data. There are two scenarios
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  ** where this risk can be ignored:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
  **   * When the pager is in no-sync mode. Corruption can follow a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  **     power failure in this case anyway.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
  **     that garbage data is never appended to the journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
  assert(pPager->fd->pMethods||pPager->noSync);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
  if( (pPager->noSync) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
    put32bits(&zHeader[sizeof(aJournalMagic)], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
  /* The random check-hash initialiser */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
  sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
  /* The initial database size */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  /* The assumed sector size for this process */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader)))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
  rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader),pPager->journalOff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  /* The journal header has been written successfully. Seek the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  ** file descriptor to the end of the journal header sector.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
    IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
    rc = sqlite3OsWrite(pPager->jfd, "\000", 1, pPager->journalOff-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
** The journal file must be open when this is called. A journal header file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
** file. See comments above function writeJournalHdr() for a description of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
** the journal header format.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
** If the header is read successfully, *nRec is set to the number of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
** page records following this header and *dbSize is set to the size of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
** database before the transaction began, in pages. Also, pPager->cksumInit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
** is set to the value read from the journal header. SQLITE_OK is returned
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
** in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
** If the journal header file appears to be corrupted, SQLITE_DONE is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
** returned and *nRec and *dbSize are not set.  If JOURNAL_HDR_SZ bytes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
** cannot be read from the journal file an error code is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
static int readJournalHdr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
  Pager *pPager, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
  i64 journalSize,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
  u32 *pNRec, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
  u32 *pDbSize
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
  unsigned char aMagic[8]; /* A buffer to hold the magic header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  i64 jrnlOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
  seekJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
    return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
  jrnlOff = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
  rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), jrnlOff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
  jrnlOff += sizeof(aMagic);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
  if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
    return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  rc = read32bits(pPager->jfd, jrnlOff, pNRec);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
  rc = read32bits(pPager->jfd, jrnlOff+4, &pPager->cksumInit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
  rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
  /* Update the assumed sector-size to match the value used by 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
  ** the process that created this journal. If this journal was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  ** created by a process other than this one, then this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
  ** is being called from within pager_playback(). The local value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
  ** of Pager.sectorSize is restored at the end of that routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
  rc = read32bits(pPager->jfd, jrnlOff+12, (u32 *)&pPager->sectorSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
** Write the supplied master journal name into the journal file for pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
** pPager at the current location. The master journal name must be the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
** thing written to a journal file. If the pager is in full-sync mode, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
** journal file descriptor is advanced to the next sector boundary before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
** anything is written. The format is:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
** + 4 bytes: PAGER_MJ_PGNO.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
** + N bytes: length of master journal name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
** + 4 bytes: N
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
** + 4 bytes: Master journal name checksum.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
** + 8 bytes: aJournalMagic[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
** The master journal page checksum is the sum of the bytes in the master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
** journal name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
** If zMaster is a NULL pointer (occurs for a single database transaction), 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
** this call is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
static int writeMasterJournal(Pager *pPager, const char *zMaster){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  int len; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
  int i; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  i64 jrnlOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
  u32 cksum = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
  char zBuf[sizeof(aJournalMagic)+2*4];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
  if( !zMaster || pPager->setMaster) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
  pPager->setMaster = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
  len = strlen(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
  for(i=0; i<len; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
    cksum += zMaster[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
  /* If in full-sync mode, advance to the next disk sector before writing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
  ** the master journal name. This is in case the previous page written to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
  ** the journal has already been synced.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
  if( pPager->fullSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
    seekJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
  jrnlOff = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
  pPager->journalOff += (len+20);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
  rc = write32bits(pPager->jfd, jrnlOff, PAGER_MJ_PGNO(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
  jrnlOff += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
  rc = sqlite3OsWrite(pPager->jfd, zMaster, len, jrnlOff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
  jrnlOff += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
  put32bits(zBuf, len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
  put32bits(&zBuf[4], cksum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
  memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
  rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
  pPager->needSync = !pPager->noSync;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
** Add or remove a page from the list of all pages that are in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
** statement journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
** The Pager keeps a separate list of pages that are currently in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
** the statement journal.  This helps the sqlite3PagerStmtCommit()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
** routine run MUCH faster for the common case where there are many
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
** pages in memory but only a few are in the statement journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
static void page_add_to_stmt_list(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
  PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
  assert( MEMDB );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
  if( !pHist->inStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
    assert( pHist->pPrevStmt==0 && pHist->pNextStmt==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
    if( pPager->pStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
      PGHDR_TO_HIST(pPager->pStmt, pPager)->pPrevStmt = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
    pHist->pNextStmt = pPager->pStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
    pPager->pStmt = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
    pHist->inStmt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
** Find a page in the hash table given its page number.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
** a pointer to the page or NULL if not found.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
  PgHdr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
  if( pPager->aHash==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
  p = pPager->aHash[pgno & (pPager->nHash-1)];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
  while( p && p->pgno!=pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
    p = p->pNextHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
  return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
** Clear the in-memory cache.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
** sets the state of the pager back to what it was when it was first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
** opened.  Any outstanding pages are invalidated and subsequent attempts
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
** to access those pages will likely result in a coredump.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
static void pager_reset(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
  PgHdr *pPg, *pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
  if( pPager->errCode ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
  for(pPg=pPager->pAll; pPg; pPg=pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
    IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
    PAGER_INCR(sqlite3_pager_pgfree_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    pNext = pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
    lruListRemove(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
    sqlite3_free(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
  assert(pPager->lru.pFirst==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
  assert(pPager->lru.pFirstSynced==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
  assert(pPager->lru.pLast==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
  pPager->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
  pPager->pAll = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
  pPager->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
  pPager->nHash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
  sqlite3_free(pPager->aHash);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
  pPager->nPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
  pPager->aHash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
  pPager->nRef = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
** Unlock the database file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
** If the pager is currently in error state, discard the contents of 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
** the cache and reset the Pager structure internal state. If there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
** an open journal-file, then the next time a shared-lock is obtained
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
** on the pager file (by this or any other process), it will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
** treated as a hot-journal and rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
static void pager_unlock(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
  if( !pPager->exclusiveMode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
    if( !MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
      if( pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
        osUnlock(pPager->fd, NO_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
      pPager->dbSize = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
      IOTRACE(("UNLOCK %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
      /* If Pager.errCode is set, the contents of the pager cache cannot be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
      ** trusted. Now that the pager file is unlocked, the contents of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
      ** cache can be discarded and the error code safely cleared.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
      if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
        pPager->errCode = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
        pager_reset(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
        if( pPager->stmtOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
          sqlite3OsClose(pPager->stfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
          sqlite3_free(pPager->aInStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
          pPager->aInStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
        if( pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
          sqlite3OsClose(pPager->jfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
          pPager->journalOpen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
          sqlite3_free(pPager->aInJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
          pPager->aInJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
        pPager->stmtOpen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
        pPager->stmtInUse = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
        pPager->journalOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
        pPager->journalStarted = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
        pPager->stmtAutoopen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
        pPager->origDbSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
    if( !MEMDB || pPager->errCode==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
      pPager->state = PAGER_UNLOCK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
      pPager->changeCountDone = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
** Execute a rollback if a transaction is active and unlock the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
** database file. If the pager has already entered the error state, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
** do not attempt the rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
static void pagerUnlockAndRollback(Pager *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
  assert( p->state>=PAGER_RESERVED || p->journalOpen==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
  if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
    sqlite3PagerRollback(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
  pager_unlock(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
** This routine ends a transaction.  A transaction is ended by either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
** a COMMIT or a ROLLBACK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
** When this routine is called, the pager has the journal file open and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
** a RESERVED or EXCLUSIVE lock on the database.  This routine will release
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
** the database lock and acquires a SHARED lock in its place if that is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
** the appropriate thing to do.  Release locks usually is appropriate,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
** unless we are in exclusive access mode or unless this is a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
** COMMIT AND BEGIN or ROLLBACK AND BEGIN operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
** The journal file is either deleted or truncated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
** TODO: Consider keeping the journal file open for temporary databases.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
** This might give a performance improvement on windows where opening
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
** a file is an expensive operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
static int pager_end_transaction(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
  int rc2 = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
  assert( !MEMDB );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
  if( pPager->state<PAGER_RESERVED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
  sqlite3PagerStmtCommit(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
  if( pPager->stmtOpen && !pPager->exclusiveMode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
    sqlite3OsClose(pPager->stfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
    pPager->stmtOpen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
  if( pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
    if( pPager->exclusiveMode 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
          && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
      pPager->journalOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
      pPager->journalStarted = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
      sqlite3OsClose(pPager->jfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
      pPager->journalOpen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
    sqlite3_free( pPager->aInJournal );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
    pPager->aInJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
      pPg->inJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
      pPg->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
      pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
      pPg->alwaysRollback = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
      pPg->pageHash = pager_pagehash(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
    pPager->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
    pPager->dirtyCache = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
    pPager->nRec = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
    assert( pPager->aInJournal==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
    assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
  if( !pPager->exclusiveMode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
    rc2 = osUnlock(pPager->fd, SHARED_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
    pPager->state = PAGER_SHARED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
  }else if( pPager->state==PAGER_SYNCED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
    pPager->state = PAGER_EXCLUSIVE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
  pPager->origDbSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
  pPager->setMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
  pPager->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
  lruListSetFirstSynced(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
  pPager->dbSize = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
  return (rc==SQLITE_OK?rc2:rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
** Compute and return a checksum for the page of data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
** This is not a real checksum.  It is really just the sum of the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
** random initial value and the page number.  We experimented with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
** a checksum of the entire data, but that was found to be too slow.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
** Note that the page number is stored at the beginning of data and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
** the checksum is stored at the end.  This is important.  If journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
** corruption occurs due to a power failure, the most likely scenario
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
** is that one end or the other of the record will be changed.  It is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
** much less likely that the two ends of the journal record will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
** correct and the middle be corrupt.  Thus, this "checksum" scheme,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
** though fast and simple, catches the mostly likely kind of corruption.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
** FIX ME:  Consider adding every 200th (or so) byte of the data to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
** checksum.  That way if a single page spans 3 or more disk sectors and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
** only the middle sector is corrupt, we will still have a reasonable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
** chance of failing the checksum and thus detecting the problem.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
static u32 pager_cksum(Pager *pPager, const u8 *aData){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
  u32 cksum = pPager->cksumInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
  int i = pPager->pageSize-200;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
  while( i>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
    cksum += aData[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
    i -= 200;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
  return cksum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
/* Forward declaration */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
static void makeClean(PgHdr*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
** Read a single page from the journal file opened on file descriptor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
** jfd.  Playback this one page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
** If useCksum==0 it means this journal does not use checksums.  Checksums
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
** are not used in statement journals because statement journals do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
** need to survive power failures.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
static int pager_playback_one_page(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
  Pager *pPager, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
  sqlite3_file *jfd,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
  i64 offset,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
  int useCksum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
  PgHdr *pPg;                   /* An existing page in the cache */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
  Pgno pgno;                    /* The page number of a page in journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
  u32 cksum;                    /* Checksum used for sanity checking */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
  u8 *aData = (u8 *)pPager->pTmpSpace;   /* Temp storage for a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
  /* useCksum should be true for the main journal and false for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
  ** statement journals.  Verify that this is always the case
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
  assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
  assert( aData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
  rc = read32bits(jfd, offset, &pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
  rc = sqlite3OsRead(jfd, aData, pPager->pageSize, offset+4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
  pPager->journalOff += pPager->pageSize + 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
  /* Sanity checking on the page.  This is more important that I originally
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
  ** thought.  If a power failure occurs while the journal is being written,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
  ** it could cause invalid data to be written into the journal.  We need to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
  ** detect this invalid data (with high probability) and ignore it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
    return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
  if( pgno>(unsigned)pPager->dbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
  if( useCksum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
    rc = read32bits(jfd, offset+pPager->pageSize+4, &cksum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
    pPager->journalOff += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
    if( pager_cksum(pPager, aData)!=cksum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
      return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
  /* If the pager is in RESERVED state, then there must be a copy of this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
  ** page in the pager cache. In this case just update the pager cache,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
  ** not the database file. The page is left marked dirty in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
  ** An exception to the above rule: If the database is in no-sync mode
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
  ** and a page is moved during an incremental vacuum then the page may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
  ** not be in the pager cache. Later: if a malloc() or IO error occurs
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
  ** during a Movepage() call, then the page may not be in the cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
  ** either. So the condition described in the above paragraph is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
  ** assert()able.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
  ** If in EXCLUSIVE state, then we update the pager cache if it exists
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  ** and the main file. The page is then marked not dirty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
  ** Ticket #1171:  The statement journal might contain page content that is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
  ** different from the page content at the start of the transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
  ** This occurs when a page is changed prior to the start of a statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
  ** then changed again within the statement.  When rolling back such a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
  ** statement we must not write to the original database unless we know
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
  ** for certain that original page contents are synced into the main rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
  ** journal.  Otherwise, a power loss might leave modified data in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
  ** database file without an entry in the rollback journal that can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
  ** restore the database to its original form.  Two conditions must be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
  ** met before writing to the database files. (1) the database must be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
  ** locked.  (2) we know that the original page content is fully synced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
  ** in the main journal either because the page is not in cache or else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  ** the page is marked as needSync==0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  pPg = pager_lookup(pPager, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
  PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
               PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
    i64 offset = (pgno-1)*(i64)pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
    rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
    if( pPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
      makeClean(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
  if( pPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
    /* No page should ever be explicitly rolled back that is in use, except
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
    ** for page 1 which is held in use in order to keep the lock on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
    ** database active. However such a page may be rolled back as a result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
    ** of an internal error resulting in an automatic call to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
    ** sqlite3PagerRollback().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
    void *pData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
    /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
    pData = PGHDR_TO_DATA(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
    memcpy(pData, aData, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
    if( pPager->xReiniter ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
      pPager->xReiniter(pPg, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
    pPg->pageHash = pager_pagehash(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
    /* If this was page 1, then restore the value of Pager.dbFileVers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
    ** Do this before any decoding. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
    if( pgno==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
    /* Decode the page just read from disk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
    CODEC1(pPager, pData, pPg->pgno, 3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
** Parameter zMaster is the name of a master journal file. A single journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
** file that referred to the master journal file has just been rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
** This routine checks if it is possible to delete the master journal file,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
** and does so if it is.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
** available for use within this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
** The master journal file contains the names of all child journals.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
** To tell if a master journal can be deleted, check to each of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
** children.  If all children are either missing or do not refer to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
** a different master journal, then this master journal can be deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
static int pager_delmaster(Pager *pPager, const char *zMaster){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
  sqlite3_vfs *pVfs = pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
  int master_open = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
  sqlite3_file *pMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
  sqlite3_file *pJournal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
  char *zMasterJournal = 0; /* Contents of master journal file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
  i64 nMasterJournal;       /* Size of master journal file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
  /* Open the master journal file exclusively in case some other process
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
  ** is running this routine also. Not that it makes too much difference.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  if( !pMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
    int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1576
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1577
  if( rc!=SQLITE_OK ) goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
  master_open = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
  if( rc!=SQLITE_OK ) goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1583
  if( nMasterJournal>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
    char *zJournal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
    char *zMasterPtr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
    int nMasterPtr = pPager->pVfs->mxPathname+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
    /* Load the entire master journal file into space obtained from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
    ** sqlite3_malloc() and pointed to by zMasterJournal. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1590
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1591
    zMasterJournal = (char *)sqlite3_malloc(nMasterJournal + nMasterPtr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
    if( !zMasterJournal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1593
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1594
      goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
    zMasterPtr = &zMasterJournal[nMasterJournal];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
    rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
    if( rc!=SQLITE_OK ) goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
    zJournal = zMasterJournal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
    while( (zJournal-zMasterJournal)<nMasterJournal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
      if( sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
        /* One of the journals pointed to by the master journal exists.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
        ** Open it and check if it points at the master journal. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1605
        ** so, return without deleting the master journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1606
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
        int c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
        int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
        rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
          goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
        rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
        sqlite3OsClose(pJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
          goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
        c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
        if( c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
          /* We have a match. Do not delete the master journal file. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
          goto delmaster_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
      zJournal += (strlen(zJournal)+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
  rc = sqlite3OsDelete(pVfs, zMaster, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1631
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1632
delmaster_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
  if( zMasterJournal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
    sqlite3_free(zMasterJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1635
  }  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1636
  if( master_open ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
    sqlite3OsClose(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1638
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1639
  sqlite3_free(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1641
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1642
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
static void pager_truncate_cache(Pager *pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
** Truncate the main file of the given pager to the number of pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1648
** indicated. Also truncate the cached representation of the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1649
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
** Might might be the case that the file on disk is smaller than nPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1651
** This can happen, for example, if we are in the middle of a transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1652
** which has extended the file size and the new pages are still all held
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
** in cache, then an INSERT or UPDATE does a statement rollback.  Some
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
** operating system implementations can get confused if you try to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
** truncate a file to some size that is larger than it currently is,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
** so detect this case and do not do the truncation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
static int pager_truncate(Pager *pPager, int nPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1660
  if( pPager->state>=PAGER_EXCLUSIVE && pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1661
    i64 currentSize, newSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1662
    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1663
    newSize = pPager->pageSize*(i64)nPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
    if( rc==SQLITE_OK && currentSize>newSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1665
      rc = sqlite3OsTruncate(pPager->fd, newSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1666
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
    pPager->dbSize = nPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
    pager_truncate_cache(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1673
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1674
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
** Set the sectorSize for the given pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1677
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1678
** The sector size is the larger of the sector size reported
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
** by sqlite3OsSectorSize() and the pageSize.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
static void setSectorSize(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
  assert(pPager->fd->pMethods||pPager->tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1683
  if( !pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1684
    /* Sector size doesn't matter for temporary files. Also, the file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
    ** may not have been opened yet, in whcih case the OsSectorSize()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
    ** call will segfault.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
    pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
  if( pPager->sectorSize<pPager->pageSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
    pPager->sectorSize = pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
** Playback the journal and thus restore the database file to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
** the state it was in before we started making changes.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
** The journal file format is as follows: 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
**  (1)  8 byte prefix.  A copy of aJournalMagic[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
**  (2)  4 byte big-endian integer which is the number of valid page records
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
**       in the journal.  If this value is 0xffffffff, then compute the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
**       number of page records from the journal size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
**  (3)  4 byte big-endian integer which is the initial value for the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
**       sanity checksum.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
**  (4)  4 byte integer which is the number of pages to truncate the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
**       database to during a rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
**  (5)  4 byte integer which is the number of bytes in the master journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
**       name.  The value may be zero (indicate that there is no master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
**       journal.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
**  (6)  N bytes of the master journal name.  The name will be nul-terminated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
**       and might be shorter than the value read from (5).  If the first byte
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
**       of the name is \000 then there is no master journal.  The master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
**       journal name is stored in UTF-8.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
**  (7)  Zero or more pages instances, each as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
**        +  4 byte page number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
**        +  pPager->pageSize bytes of data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
**        +  4 byte checksum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
** When we speak of the journal header, we mean the first 6 items above.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
** Each entry in the journal is an instance of the 7th item.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
** Call the value from the second bullet "nRec".  nRec is the number of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
** valid page entries in the journal.  In most cases, you can compute the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
** value of nRec from the size of the journal file.  But if a power
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
** failure occurred while the journal was being written, it could be the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
** case that the size of the journal file had already been increased but
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
** the extra entries had not yet made it safely to disk.  In such a case,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
** the value of nRec computed from the file size would be too large.  For
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1731
** that reason, we always use the nRec value in the header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1732
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
** If the nRec value is 0xffffffff it means that nRec should be computed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
** from the file size.  This value is used when the user selects the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
** no-sync option for the journal.  A power failure could lead to corruption
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
** in this case.  But for things like temporary table (which will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
** deleted when the power is restored) we don't care.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1738
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1739
** If the file opened as the journal file is not a well-formed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
** journal file then all pages up to the first corrupted page are rolled
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
** back (or no pages if the journal header is corrupted). The journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
** is then deleted and SQLITE_OK returned, just as if no corruption had
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
** been encountered.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1745
** If an I/O or malloc() error occurs, the journal-file is not deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1746
** and an error code is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
static int pager_playback(Pager *pPager, int isHot){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
  sqlite3_vfs *pVfs = pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
  i64 szJ;                 /* Size of the journal file in bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
  u32 nRec;                /* Number of Records in the journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
  int i;                   /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
  Pgno mxPg = 0;           /* Size of the original file in pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
  int rc;                  /* Result code of a subroutine */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
  char *zMaster = 0;       /* Name of master journal file if any */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1756
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1757
  /* Figure out how many records are in the journal.  Abort early if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1758
  ** the journal is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
  assert( pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
  if( rc!=SQLITE_OK || szJ==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
    goto end_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
  /* Read the master journal name from the journal, if it is present.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
  ** If a master journal file name is specified, but the file is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
  ** present on disk, then the journal is not hot and does not need to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
  ** played back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
  zMaster = pPager->pTmpSpace;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
  assert( rc!=SQLITE_DONE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
  if( rc!=SQLITE_OK 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1775
   || (zMaster[0] && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1776
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
    zMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
    goto end_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
  pPager->journalOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1782
  zMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1783
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
  /* This loop terminates either when the readJournalHdr() call returns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
  ** SQLITE_DONE or an IO error occurs. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
  while( 1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
    /* Read the next journal header from the journal file.  If there are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
    ** not enough bytes left in the journal file for a complete header, or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
    ** it is corrupted, then a process must of failed while writing it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
    ** This indicates nothing more needs to be rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
    rc = readJournalHdr(pPager, szJ, &nRec, &mxPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
    if( rc!=SQLITE_OK ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
      if( rc==SQLITE_DONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
        rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
      goto end_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
    /* If nRec is 0xffffffff, then this journal was created by a process
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
    ** working in no-sync mode. This means that the rest of the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
    ** file consists of pages, there are no more journal headers. Compute
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
    ** the value of nRec based on this assumption.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
    if( nRec==0xffffffff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
      nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
    /* If nRec is 0 and this rollback is of a transaction created by this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
    ** process and if this is the final header in the journal, then it means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1813
    ** that this part of the journal was being filled but has not yet been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1814
    ** synced to disk.  Compute the number of pages based on the remaining
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
    ** size of the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
    ** The third term of the test was added to fix ticket #2565.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
    if( nRec==0 && !isHot &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1820
        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1821
      nRec = (szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
    /* If this is the first header read from the journal, truncate the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
    ** database file back to its original size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1828
      rc = pager_truncate(pPager, mxPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1829
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
        goto end_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1833
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1834
    /* Copy original pages out of the journal and back into the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1835
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1836
    for(i=0; i<nRec; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
      rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
        if( rc==SQLITE_DONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
          rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
          pPager->journalOff = szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1844
          goto end_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1845
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1846
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
  /*NOTREACHED*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
  assert( 0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1851
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1852
end_playback:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
    zMaster = pPager->pTmpSpace;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1858
    rc = pager_end_transaction(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1859
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1860
  if( rc==SQLITE_OK && zMaster[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
    /* If there was a master journal and this routine will return success,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
    ** see if it is possible to delete the master journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
    rc = pager_delmaster(pPager, zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1865
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1866
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
  /* The Pager.sectorSize variable may have been updated while rolling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
  ** back a journal created by a process with a different sector size
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
  ** value. Reset it to the correct value for this process.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
  setSectorSize(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1873
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1874
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1875
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1876
** Playback the statement journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
** This is similar to playing back the transaction journal but with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
** a few extra twists.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
**    (1)  The number of pages in the database file at the start of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
**         the statement is stored in pPager->stmtSize, not in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
**         journal file itself.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1884
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1885
**    (2)  In addition to playing back the statement journal, also
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
**         playback all pages of the transaction journal beginning
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
**         at offset pPager->stmtJSize.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1888
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1889
static int pager_stmt_playback(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
  i64 szJ;                 /* Size of the full journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
  i64 hdrOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
  int nRec;                /* Number of Records */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
  int i;                   /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1895
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1896
  szJ = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
#ifndef NDEBUG 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
    i64 os_szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
    rc = sqlite3OsFileSize(pPager->jfd, &os_szJ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
    if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
    assert( szJ==os_szJ );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1903
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1904
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
  /* Set hdrOff to be the offset just after the end of the last journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
  ** page written before the first journal-header for this statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
  ** transaction was written, or the end of the file if no journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
  ** header was written.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1911
  hdrOff = pPager->stmtHdrOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1912
  assert( pPager->fullSync || !hdrOff );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
  if( !hdrOff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
    hdrOff = szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1916
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1917
  /* Truncate the database back to its original size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
  rc = pager_truncate(pPager, pPager->stmtSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
  assert( pPager->state>=PAGER_SHARED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1921
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1922
  /* Figure out how many records are in the statement journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1923
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1924
  assert( pPager->stmtInUse && pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
  nRec = pPager->stmtNRec;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1926
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1927
  /* Copy original pages out of the statement journal and back into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
  ** database file.  Note that the statement journal omits checksums from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
  ** each record since power-failure recovery is not important to statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
  ** journals.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1931
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1932
  for(i=0; i<nRec; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
    i64 offset = i*(4+pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
    rc = pager_playback_one_page(pPager, pPager->stfd, offset, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
    assert( rc!=SQLITE_DONE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1937
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1938
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1939
  /* Now roll some pages back from the transaction journal. Pager.stmtJSize
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
  ** was the size of the journal file when this statement was started, so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
  ** everything after that needs to be rolled back, either into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
  ** database, the memory cache, or both.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1943
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1944
  ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
  ** of the first journal header written during this statement transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1947
  pPager->journalOff = pPager->stmtJSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1948
  pPager->cksumInit = pPager->stmtCksum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
  while( pPager->journalOff < hdrOff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
    rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
    assert( rc!=SQLITE_DONE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1954
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1955
  while( pPager->journalOff < szJ ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
    u32 nJRec;         /* Number of Journal Records */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
    u32 dummy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
    rc = readJournalHdr(pPager, szJ, &nJRec, &dummy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
      assert( rc!=SQLITE_DONE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
      goto end_stmt_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
    if( nJRec==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
      nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
    for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
      rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
      assert( rc!=SQLITE_DONE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      if( rc!=SQLITE_OK ) goto end_stmt_playback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1971
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
  pPager->journalOff = szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
end_stmt_playback:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
  if( rc==SQLITE_OK) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
    pPager->journalOff = szJ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
    /* pager_reload_cache(pPager); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1979
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1980
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
** Change the maximum number of in-memory pages that are allowed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
  if( mxPage>10 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1988
    pPager->mxPage = mxPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1989
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
    pPager->mxPage = 10;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
** Adjust the robustness of the database to damage due to OS crashes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
** or power failures by changing the number of syncs()s when writing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
** the rollback journal.  There are three levels:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1998
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1999
**    OFF       sqlite3OsSync() is never called.  This is the default
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2000
**              for temporary and transient files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2001
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
**    NORMAL    The journal is synced once before writes begin on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
**              database.  This is normally adequate protection, but
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
**              it is theoretically possible, though very unlikely,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
**              that an inopertune power failure could leave the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
**              in a state which would cause damage to the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
**              when it is rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2008
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2009
**    FULL      The journal is synced twice before writes begin on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
**              database (with some additional information - the nRec field
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
**              of the journal header - being written in between the two
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
**              syncs).  If we assume that writing a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
**              single disk sector is atomic, then this mode provides
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
**              assurance that the journal will not be corrupted to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
**              point of causing damage to the database during rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2016
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2017
** Numeric values associated with these states are OFF==1, NORMAL=2,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
** and FULL=3.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int full_fsync){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
  pPager->noSync =  level==1 || pPager->tempFile;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
  pPager->fullSync = level==3 && !pPager->tempFile;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
  pPager->sync_flags = (full_fsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
  if( pPager->noSync ) pPager->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2028
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2029
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
** The following global variable is incremented whenever the library
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
** attempts to open a temporary file.  This information is used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
** testing and analysis only.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2033
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2034
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
int sqlite3_opentemp_count = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
** Open a temporary file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2040
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2041
** Write the file descriptor into *fd.  Return SQLITE_OK on success or some
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
** other error code if we fail. The OS will automatically delete the temporary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
** file when it is closed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
static int sqlite3PagerOpentemp(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
  sqlite3_vfs *pVfs,    /* The virtual file system layer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
  sqlite3_file *pFile,  /* Write the file descriptor here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
  char *zFilename,      /* Name of the file.  Might be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
  int vfsFlags          /* Flags passed through to the VFS */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2050
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2051
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
  assert( zFilename!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
  vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
            SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
  rc = sqlite3OsOpen(pVfs, zFilename, pFile, vfsFlags, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
  assert( rc!=SQLITE_OK || pFile->pMethods );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2063
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2064
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2065
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2066
//void fopenTest()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
//{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
//	     FILE *fp = fopen("c:\\data\\redfivelabs\\temp\\sqlite.log", "w+");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
//  if (fp != NULL)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
//  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
//	  char tmp[256];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
//	  sprintf(tmp, "Hallo Welt");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
//	  fwrite(tmp, strlen(tmp), 1, fp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
//	  fclose(fp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
//  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
//  return 191280;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
//}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2079
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2080
** Create a new page cache and put a pointer to the page cache in *ppPager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
** The file to be cached need not exist.  The file is not locked until
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
** the first call to sqlite3PagerGet() and is only held open until the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
** last page is released using sqlite3PagerUnref().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2084
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2085
** If zFilename is NULL then a randomly-named temporary file is created
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
** and used as the file to be cached.  The file will be deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2087
** automatically when it is closed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2088
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2089
** If zFilename is ":memory:" then all information is held in cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
** It is never written to disk.  This can be used to implement an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
** in-memory database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2092
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2093
int sqlite3PagerOpen(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
  sqlite3_vfs *pVfs,       /* The virtual file system to use */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
  Pager **ppPager,         /* Return the Pager structure here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
  const char *zFilename,   /* Name of the database file to open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
  int nExtra,              /* Extra bytes append to each in-memory page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
  int flags,               /* flags controlling this file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
  int vfsFlags             /* flags passed through to sqlite3_vfs.xOpen() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2100
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2101
  u8 *pPtr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
  Pager *pPager = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
  int tempFile = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
  int memDb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
  int readOnly = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
  int journalFileSize = sqlite3JournalSize(pVfs);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
  int nDefaultPage = SQLITE_DEFAULT_PAGE_SIZE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
  char *zPathname;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
  int nPathname;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2115
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2116
  /* The default return is a NULL pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
  *ppPager = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
  /* Compute the full pathname */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
  nPathname = pVfs->mxPathname+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
  zPathname = (char*)sqlite3_malloc(nPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
  if( zPathname==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
  if( zFilename && zFilename[0] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
#ifndef SQLITE_OMIT_MEMORYDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
    if( strcmp(zFilename,":memory:")==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
      memDb = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
      zPathname[0] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
    }else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2132
    {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2134
      rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
    rc = sqlite3OsGetTempname(pVfs, nPathname, zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
    sqlite3_free(zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2141
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2142
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
 nPathname = strlen(zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
  /* Allocate memory for the pager structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
  pPager = (Pager*)sqlite3MallocZero(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
    sizeof(*pPager) +           /* Pager structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
    journalFileSize +           /* The journal file structure */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
    pVfs->szOsFile * 2 +        /* The db and stmt journal files */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
    4*nPathname + 40            /* zFilename, zDirectory, zJournal, zStmtJrnl */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
  if( !pPager ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
    sqlite3_free(zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
  pPtr = (u8 *)&pPager[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
  pPager->vfsFlags = vfsFlags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
  pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
  pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
  pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
  pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
  pPager->zDirectory = &pPager->zFilename[nPathname+1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
  pPager->zJournal = &pPager->zDirectory[nPathname+1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
  pPager->zStmtJrnl = &pPager->zJournal[nPathname+10];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
  pPager->pVfs = pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
  memcpy(pPager->zFilename, zPathname, nPathname+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
  sqlite3_free(zPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
  /* Open the pager file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
  if( zFilename && zFilename[0] && !memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
    if( nPathname>(pVfs->mxPathname - sizeof("-journal")) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
      rc = SQLITE_CANTOPEN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
      int fout = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
		rc = winOpen(pVfs, pPager->zFilename, pPager->fd,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
                         pPager->vfsFlags, &fout);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
      readOnly = (fout&SQLITE_OPEN_READONLY);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
      /* If the file was successfully opened for read/write access,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
      ** choose a default page size in case we have to create the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
      ** database file. The default page size is the maximum of:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2186
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2187
      **    + SQLITE_DEFAULT_PAGE_SIZE,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
      **    + The value returned by sqlite3OsSectorSize()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
      **    + The largest page size that can be written atomically.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
      if( rc==SQLITE_OK && !readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
        int iSectorSize = sqlite3OsSectorSize(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
        if( nDefaultPage<iSectorSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
          nDefaultPage = iSectorSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2195
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2196
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
        {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
          int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
          int ii;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
          assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
          assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
          assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
          for(ii=nDefaultPage; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) nDefaultPage = ii;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
        if( nDefaultPage>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
          nDefaultPage = SQLITE_MAX_DEFAULT_PAGE_SIZE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
  }else if( !memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
    /* If a temporary file is requested, it is not opened immediately.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
    ** In this case we accept the default page size and delay actually
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
    ** opening the file until the first call to OsWrite().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
    */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
    tempFile = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
    pPager->state = PAGER_EXCLUSIVE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2220
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2221
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2222
  if( pPager && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
    pPager->pTmpSpace = (char *)sqlite3_malloc(nDefaultPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2224
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2225
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
  /* If an error occured in either of the blocks above.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
  ** Free the Pager structure and close the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
  ** Since the pager is not allocated there is no need to set 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
  ** any Pager.errMask variables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
  if( !pPager || !pPager->pTmpSpace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
    sqlite3OsClose(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
    sqlite3_free(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
    return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2236
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2237
  PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
  /* Fill in Pager.zDirectory[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
  memcpy(pPager->zDirectory, pPager->zFilename, nPathname+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
  for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
  if( i>0 ) pPager->zDirectory[i-1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
  /* Fill in Pager.zJournal[] and Pager.zStmtJrnl[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
  memcpy(pPager->zJournal, pPager->zFilename, nPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
  memcpy(&pPager->zJournal[nPathname], "-journal", 9);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
  memcpy(pPager->zStmtJrnl, pPager->zFilename, nPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
  memcpy(&pPager->zStmtJrnl[nPathname], "-stmtjrnl", 10);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
  /* pPager->journalOpen = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
  pPager->useJournal = useJournal && !memDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
  pPager->noReadlock = noReadlock && readOnly;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
  /* pPager->stmtOpen = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
  /* pPager->stmtInUse = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
  /* pPager->nRef = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
  pPager->dbSize = memDb-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
  pPager->pageSize = nDefaultPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
  /* pPager->stmtSize = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
  /* pPager->stmtJSize = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2261
  /* pPager->nPage = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2262
  pPager->mxPage = 100;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2263
  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2264
  /* pPager->state = PAGER_UNLOCK; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2265
  assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2266
  /* pPager->errMask = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2267
  pPager->tempFile = tempFile;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2268
  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2269
          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2270
  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2271
  pPager->exclusiveMode = tempFile; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2272
  pPager->memDb = memDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2273
  pPager->readOnly = readOnly;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2274
  /* pPager->needSync = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2275
  pPager->noSync = pPager->tempFile || !useJournal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2276
  pPager->fullSync = (pPager->noSync?0:1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2277
  pPager->sync_flags = SQLITE_SYNC_NORMAL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2278
  /* pPager->pFirst = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2279
  /* pPager->pFirstSynced = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2280
  /* pPager->pLast = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2281
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2282
  assert(pPager->fd->pMethods||memDb||tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2283
  if( !memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2284
    setSectorSize(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2285
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2286
  /* pPager->pBusyHandler = 0; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2287
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2288
  *ppPager = pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2289
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2290
  pPager->iInUseMM = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2291
  pPager->iInUseDB = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2292
  if( !memDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2293
    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2294
    sqlite3_mutex_enter(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2295
    pPager->pNext = sqlite3PagerList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2296
    if( sqlite3PagerList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2297
      assert( sqlite3PagerList->pPrev==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2298
      sqlite3PagerList->pPrev = pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2299
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2300
    pPager->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2301
    sqlite3PagerList = pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2302
    sqlite3_mutex_leave(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2303
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2304
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2305
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2306
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2307
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2308
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2309
** Set the busy handler function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2310
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2311
void sqlite3PagerSetBusyhandler(Pager *pPager, BusyHandler *pBusyHandler){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2312
  pPager->pBusyHandler = pBusyHandler;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2313
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2316
** Set the destructor for this pager.  If not NULL, the destructor is called
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2317
** when the reference count on each page reaches zero.  The destructor can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2318
** be used to clean up information in the extra segment appended to each page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2319
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2320
** The destructor is not called as a result sqlite3PagerClose().  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2321
** Destructors are only called by sqlite3PagerUnref().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2322
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2323
void sqlite3PagerSetDestructor(Pager *pPager, void (*xDesc)(DbPage*,int)){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2324
  pPager->xDestructor = xDesc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2325
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2326
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2327
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2328
** Set the reinitializer for this pager.  If not NULL, the reinitializer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2329
** is called when the content of a page in cache is restored to its original
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2330
** value as a result of a rollback.  The callback gives higher-level code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2331
** an opportunity to restore the EXTRA section to agree with the restored
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2332
** page data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2333
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2334
void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2335
  pPager->xReiniter = xReinit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2336
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2337
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2338
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2339
** Set the page size to *pPageSize. If the suggest new page size is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2340
** inappropriate, then an alternative page size is set to that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2341
** value before returning.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2342
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2343
int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2344
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2345
  u16 pageSize = *pPageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2346
  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2347
  if( pageSize && pageSize!=pPager->pageSize 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2348
   && !pPager->memDb && pPager->nRef==0 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2349
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2350
    char *pNew = (char *)sqlite3_malloc(pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2351
    if( !pNew ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2352
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2353
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2354
      pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2355
      pager_reset(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2356
      pPager->pageSize = pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2357
      setSectorSize(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2358
      sqlite3_free(pPager->pTmpSpace);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2359
      pPager->pTmpSpace = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2360
      pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2361
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2362
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2363
  *pPageSize = pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2364
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2365
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2366
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2367
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2368
** Return a pointer to the "temporary page" buffer held internally
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2369
** by the pager.  This is a buffer that is big enough to hold the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2370
** entire content of a database page.  This buffer is used internally
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2371
** during rollback and will be overwritten whenever a rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2372
** occurs.  But other modules are free to use it too, as long as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2373
** no rollbacks are happening.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2374
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2375
void *sqlite3PagerTempSpace(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2376
  return pPager->pTmpSpace;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2377
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2378
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2379
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2380
** Attempt to set the maximum database page count if mxPage is positive. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2381
** Make no changes if mxPage is zero or negative.  And never reduce the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2382
** maximum page count below the current size of the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2383
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2384
** Regardless of mxPage, return the current maximum page count.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2385
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2386
int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2387
  if( mxPage>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2388
    pPager->mxPgno = mxPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2389
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2390
  sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2391
  return pPager->mxPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2392
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2393
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2394
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2395
** The following set of routines are used to disable the simulated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2396
** I/O error mechanism.  These routines are used to avoid simulated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2397
** errors in places where we do not care about errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2398
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2399
** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2400
** and generate no code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2401
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2402
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2403
extern int sqlite3_io_error_pending;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2404
extern int sqlite3_io_error_hit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2405
static int saved_cnt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2406
void disable_simulated_io_errors(void){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2407
  saved_cnt = sqlite3_io_error_pending;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2408
  sqlite3_io_error_pending = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2409
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2410
void enable_simulated_io_errors(void){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2411
  sqlite3_io_error_pending = saved_cnt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2412
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2413
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2414
# define disable_simulated_io_errors()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2415
# define enable_simulated_io_errors()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2416
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2417
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2418
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2419
** Read the first N bytes from the beginning of the file into memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2420
** that pDest points to. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2421
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2422
** No error checking is done. The rational for this is that this function 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2423
** may be called even if the file does not exist or contain a header. In 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2424
** these cases sqlite3OsRead() will return an error, to which the correct 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2425
** response is to zero the memory at pDest and continue.  A real IO error 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2426
** will presumably recur and be picked up later (Todo: Think about this).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2427
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2428
int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2429
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2430
  memset(pDest, 0, N);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2431
  assert(MEMDB||pPager->fd->pMethods||pPager->tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2432
  if( pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2433
    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2434
    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2435
    if( rc==SQLITE_IOERR_SHORT_READ ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2436
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2437
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2438
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2439
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2440
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2441
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2442
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2443
** Return the total number of pages in the disk file associated with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2444
** pPager. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2445
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2446
** If the PENDING_BYTE lies on the page directly after the end of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2447
** file, then consider this page part of the file too. For example, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2448
** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2449
** file is 4096 bytes, 5 is returned instead of 4.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2450
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2451
int sqlite3PagerPagecount(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2452
  i64 n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2453
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2454
  assert( pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2455
  if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2456
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2457
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2458
  if( pPager->dbSize>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2459
    n = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2460
  } else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2461
    assert(pPager->fd->pMethods||pPager->tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2462
    if( (pPager->fd->isOpen)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2463
     && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2464
      pPager->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2465
      pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2466
      pPager->nRef--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2467
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2468
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2469
    if( n>0 && n<pPager->pageSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2470
      n = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2471
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2472
      n /= pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2473
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2474
    if( pPager->state!=PAGER_UNLOCK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2475
      pPager->dbSize = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2476
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2477
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2478
  if( n==(PENDING_BYTE/pPager->pageSize) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2479
    n++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2480
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2481
  if( n>pPager->mxPgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2482
    pPager->mxPgno = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2483
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2484
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2485
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2486
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2487
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2488
#ifndef SQLITE_OMIT_MEMORYDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2489
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2490
** Clear a PgHistory block
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2491
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2492
static void clearHistory(PgHistory *pHist){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2493
  sqlite3_free(pHist->pOrig);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2494
  sqlite3_free(pHist->pStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2495
  pHist->pOrig = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2496
  pHist->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2497
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2498
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2499
#define clearHistory(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2500
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2501
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2502
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2503
** Forward declaration
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2504
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2505
static int syncJournal(Pager*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2506
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2507
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2508
** Unlink pPg from its hash chain. Also set the page number to 0 to indicate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2509
** that the page is not part of any hash chain. This is required because the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2510
** sqlite3PagerMovepage() routine can leave a page in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2511
** pNextFree/pPrevFree list that is not a part of any hash-chain.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2512
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2513
static void unlinkHashChain(Pager *pPager, PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2514
  if( pPg->pgno==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2515
    assert( pPg->pNextHash==0 && pPg->pPrevHash==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2516
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2517
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2518
  if( pPg->pNextHash ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2519
    pPg->pNextHash->pPrevHash = pPg->pPrevHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2520
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2521
  if( pPg->pPrevHash ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2522
    assert( pPager->aHash[pPg->pgno & (pPager->nHash-1)]!=pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2523
    pPg->pPrevHash->pNextHash = pPg->pNextHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2524
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2525
    int h = pPg->pgno & (pPager->nHash-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2526
    pPager->aHash[h] = pPg->pNextHash;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2527
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2528
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2529
    clearHistory(PGHDR_TO_HIST(pPg, pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2530
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2531
  pPg->pgno = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2532
  pPg->pNextHash = pPg->pPrevHash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2533
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2535
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2536
** Unlink a page from the free list (the list of all pages where nRef==0)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2537
** and from its hash collision chain.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2538
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2539
static void unlinkPage(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2540
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2541
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2542
  /* Unlink from free page list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2543
  lruListRemove(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2544
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2545
  /* Unlink from the pgno hash table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2546
  unlinkHashChain(pPager, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2547
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2548
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2549
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2550
** This routine is used to truncate the cache when a database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2551
** is truncated.  Drop from the cache all pages whose pgno is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2552
** larger than pPager->dbSize and is unreferenced.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2553
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2554
** Referenced pages larger than pPager->dbSize are zeroed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2555
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2556
** Actually, at the point this routine is called, it would be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2557
** an error to have a referenced page.  But rather than delete
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2558
** that page and guarantee a subsequent segfault, it seems better
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2559
** to zero it and hope that we error out sanely.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2560
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2561
static void pager_truncate_cache(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2562
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2563
  PgHdr **ppPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2564
  int dbSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2565
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2566
  ppPg = &pPager->pAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2567
  while( (pPg = *ppPg)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2568
    if( pPg->pgno<=dbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2569
      ppPg = &pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2570
    }else if( pPg->nRef>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2571
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2572
      ppPg = &pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2573
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2574
      *ppPg = pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2575
      IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2576
      PAGER_INCR(sqlite3_pager_pgfree_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2577
      unlinkPage(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2578
      makeClean(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2579
      sqlite3_free(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2580
      pPager->nPage--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2581
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2582
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2583
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2584
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2585
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2586
** Try to obtain a lock on a file.  Invoke the busy callback if the lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2587
** is currently not available.  Repeat until the busy callback returns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2588
** false or until the lock succeeds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2589
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2590
** Return SQLITE_OK on success and an error code if we cannot obtain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2591
** the lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2592
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2593
static int pager_wait_on_lock(Pager *pPager, int locktype){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2594
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2595
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2596
  /* The OS lock values must be the same as the Pager lock values */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2597
  assert( PAGER_SHARED==SHARED_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2598
  assert( PAGER_RESERVED==RESERVED_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2599
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2600
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2601
  /* If the file is currently unlocked then the size must be unknown */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2602
  assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2603
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2604
  if( pPager->state>=locktype ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2605
    rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2606
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2607
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2608
      rc = sqlite3OsLock(pPager->fd, locktype);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2609
    }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2610
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2611
      pPager->state = locktype;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2612
      IOTRACE(("LOCK %p %d\n", pPager, locktype))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2613
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2614
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2615
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2616
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2617
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2618
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2619
** Truncate the file to the number of pages specified.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2620
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2621
int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2622
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2623
  assert( pPager->state>=PAGER_SHARED || MEMDB );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2624
  sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2625
  if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2626
    rc = pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2627
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2628
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2629
  if( nPage>=(unsigned)pPager->dbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2630
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2631
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2632
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2633
    pPager->dbSize = nPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2634
    pager_truncate_cache(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2635
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2636
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2637
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2638
  rc = syncJournal(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2639
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2640
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2641
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2642
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2643
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2644
  /* Get an exclusive lock on the database before truncating. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2645
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2646
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2647
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2648
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2649
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2650
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2651
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2652
  rc = pager_truncate(pPager, nPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2653
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2654
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2656
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2657
** Shutdown the page cache.  Free all memory and close all files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2658
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2659
** If a transaction was in progress when this routine is called, that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2660
** transaction is rolled back.  All outstanding pages are invalidated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2661
** and their memory is freed.  Any attempt to use a page associated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2662
** with this page cache after this function returns will likely
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2663
** result in a coredump.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2664
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2665
** This function always succeeds. If a transaction is active an attempt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2666
** is made to roll it back. If an error occurs during the rollback 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2667
** a hot journal may be left in the filesystem but no error is returned
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2668
** to the caller.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2669
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2670
int sqlite3PagerClose(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2671
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2672
  if( !MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2673
    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2674
    sqlite3_mutex_enter(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2675
    if( pPager->pPrev ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2676
      pPager->pPrev->pNext = pPager->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2677
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2678
      sqlite3PagerList = pPager->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2679
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2680
    if( pPager->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2681
      pPager->pNext->pPrev = pPager->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2682
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2683
    sqlite3_mutex_leave(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2684
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2685
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2686
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2687
  disable_simulated_io_errors();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2688
  pPager->errCode = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2689
  pPager->exclusiveMode = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2690
  pager_reset(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2691
  pagerUnlockAndRollback(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2692
  enable_simulated_io_errors();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2693
  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2694
  IOTRACE(("CLOSE %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2695
  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2696
  if( pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2697
    sqlite3OsClose(pPager->jfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2698
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2699
  sqlite3_free(pPager->aInJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2700
  if( pPager->stmtOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2701
    sqlite3OsClose(pPager->stfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2702
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2703
  sqlite3OsClose(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2704
  /* Temp files are automatically deleted by the OS
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2705
  ** if( pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2706
  **   sqlite3OsDelete(pPager->zFilename);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2707
  ** }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2708
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2709
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2710
  sqlite3_free(pPager->aHash);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2711
  sqlite3_free(pPager->pTmpSpace);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2712
  sqlite3_free(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2713
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2714
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2715
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2716
#if !defined(NDEBUG) || defined(SQLITE_TEST)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2717
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2718
** Return the page number for the given page data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2719
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2720
Pgno sqlite3PagerPagenumber(DbPage *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2721
  return p->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2722
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2723
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2724
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2725
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2726
** The page_ref() function increments the reference count for a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2727
** If the page is currently on the freelist (the reference count is zero) then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2728
** remove it from the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2729
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2730
** For non-test systems, page_ref() is a macro that calls _page_ref()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2731
** online of the reference count is zero.  For test systems, page_ref()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2732
** is a real function so that we can set breakpoints and trace it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2733
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2734
static void _page_ref(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2735
  if( pPg->nRef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2736
    /* The page is currently on the freelist.  Remove it. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2737
    lruListRemove(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2738
    pPg->pPager->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2739
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2740
  pPg->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2741
  REFINFO(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2742
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2743
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2744
  static void page_ref(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2745
    if( pPg->nRef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2746
      _page_ref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2747
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2748
      pPg->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2749
      REFINFO(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2750
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2751
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2752
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2753
# define page_ref(P)   ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2754
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2755
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2756
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2757
** Increment the reference count for a page.  The input pointer is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2758
** a reference to the page data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2759
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2760
int sqlite3PagerRef(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2761
  pagerEnter(pPg->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2762
  page_ref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2763
  pagerLeave(pPg->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2764
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2765
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2766
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2767
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2768
** Sync the journal.  In other words, make sure all the pages that have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2769
** been written to the journal have actually reached the surface of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2770
** disk.  It is not safe to modify the original database file until after
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2771
** the journal has been synced.  If the original database is modified before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2772
** the journal is synced and a power failure occurs, the unsynced journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2773
** data would be lost and we would be unable to completely rollback the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2774
** database changes.  Database corruption would occur.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2775
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2776
** This routine also updates the nRec field in the header of the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2777
** (See comments on the pager_playback() routine for additional information.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2778
** If the sync mode is FULL, two syncs will occur.  First the whole journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2779
** is synced, then the nRec field is updated, then a second sync occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2780
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2781
** For temporary databases, we do not care if we are able to rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2782
** after a power failure, so no sync occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2783
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2784
** If the IOCAP_SEQUENTIAL flag is set for the persistent media on which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2785
** the database is stored, then OsSync() is never called on the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2786
** file. In this case all that is required is to update the nRec field in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2787
** the journal header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2788
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2789
** This routine clears the needSync field of every page current held in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2790
** memory.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2791
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2792
static int syncJournal(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2793
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2794
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2795
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2796
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2797
  /* Sync the journal before modifying the main database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2798
  ** (assuming there is a journal and it needs to be synced.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2799
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2800
  if( pPager->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2801
    if( !pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2802
      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2803
      assert( pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2804
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2805
      /* assert( !pPager->noSync ); // noSync might be set if synchronous
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2806
      ** was turned off after the transaction was started.  Ticket #615 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2807
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2808
      {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2809
        /* Make sure the pPager->nRec counter we are keeping agrees
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2810
        ** with the nRec computed from the size of the journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2811
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2812
        i64 jSz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2813
        rc = sqlite3OsFileSize(pPager->jfd, &jSz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2814
        if( rc!=0 ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2815
        assert( pPager->journalOff==jSz );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2816
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2817
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2818
      if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2819
        /* Write the nRec value into the journal file header. If in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2820
        ** full-synchronous mode, sync the journal first. This ensures that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2821
        ** all data has really hit the disk before nRec is updated to mark
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2822
        ** it as a candidate for rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2823
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2824
        ** This is not required if the persistent media supports the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2825
        ** SAFE_APPEND property. Because in this case it is not possible 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2826
        ** for garbage data to be appended to the file, the nRec field
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2827
        ** is populated with 0xFFFFFFFF when the journal header is written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2828
        ** and never needs to be updated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2829
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2830
        i64 jrnlOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2831
        if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2832
          PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2833
          IOTRACE(("JSYNC %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2834
          rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2835
          if( rc!=0 ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2836
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2837
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2838
        jrnlOff = pPager->journalHdr + sizeof(aJournalMagic);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2839
        IOTRACE(("JHDR %p %lld %d\n", pPager, jrnlOff, 4));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2840
        rc = write32bits(pPager->jfd, jrnlOff, pPager->nRec);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2841
        if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2842
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2843
      if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2844
        PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2845
        IOTRACE(("JSYNC %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2846
        rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags| 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2847
          (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2848
        );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2849
        if( rc!=0 ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2850
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2851
      pPager->journalStarted = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2852
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2853
    pPager->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2854
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2855
    /* Erase the needSync flag from every page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2856
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2857
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2858
      pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2859
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2860
    lruListSetFirstSynced(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2861
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2862
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2863
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2864
  /* If the Pager.needSync flag is clear then the PgHdr.needSync
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2865
  ** flag must also be clear for all pages.  Verify that this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2866
  ** invariant is true.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2867
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2868
  else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2869
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2870
      assert( pPg->needSync==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2871
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2872
    assert( pPager->lru.pFirstSynced==pPager->lru.pFirst );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2873
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2874
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2875
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2876
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2877
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2879
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2880
** Merge two lists of pages connected by pDirty and in pgno order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2881
** Do not both fixing the pPrevDirty pointers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2882
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2883
static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2884
  PgHdr result, *pTail;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2885
  pTail = &result;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2886
  while( pA && pB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2887
    if( pA->pgno<pB->pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2888
      pTail->pDirty = pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2889
      pTail = pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2890
      pA = pA->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2891
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2892
      pTail->pDirty = pB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2893
      pTail = pB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2894
      pB = pB->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2895
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2896
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2897
  if( pA ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2898
    pTail->pDirty = pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2899
  }else if( pB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2900
    pTail->pDirty = pB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2901
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2902
    pTail->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2903
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2904
  return result.pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2905
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2906
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2907
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2908
** Sort the list of pages in accending order by pgno.  Pages are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2909
** connected by pDirty pointers.  The pPrevDirty pointers are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2910
** corrupted by this sort.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2911
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2912
#define N_SORT_BUCKET_ALLOC 25
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2913
#define N_SORT_BUCKET       25
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2914
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2915
  int sqlite3_pager_n_sort_bucket = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2916
  #undef N_SORT_BUCKET
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2917
  #define N_SORT_BUCKET \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2918
   (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2919
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2920
static PgHdr *sort_pagelist(PgHdr *pIn){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2921
  PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2922
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2923
  memset(a, 0, sizeof(a));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2924
  while( pIn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2925
    p = pIn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2926
    pIn = p->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2927
    p->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2928
    for(i=0; i<N_SORT_BUCKET-1; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2929
      if( a[i]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2930
        a[i] = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2931
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2932
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2933
        p = merge_pagelist(a[i], p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2934
        a[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2935
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2936
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2937
    if( i==N_SORT_BUCKET-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2938
      /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2939
      ** elements in the input list. This is possible, but impractical.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2940
      ** Testing this line is the point of global variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2941
      ** sqlite3_pager_n_sort_bucket.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2942
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2943
      a[i] = merge_pagelist(a[i], p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2944
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2945
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2946
  p = a[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2947
  for(i=1; i<N_SORT_BUCKET; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2948
    p = merge_pagelist(p, a[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2949
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2950
  return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2951
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2952
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2953
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2954
** Given a list of pages (connected by the PgHdr.pDirty pointer) write
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2955
** every one of those pages out to the database file and mark them all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2956
** as clean.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2957
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2958
static int pager_write_pagelist(PgHdr *pList){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2959
  Pager *pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2960
  PgHdr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2961
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2962
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2963
  if( pList==0 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2964
  pPager = pList->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2965
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2966
  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2967
  ** database file. If there is already an EXCLUSIVE lock, the following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2968
  ** calls to sqlite3OsLock() are no-ops.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2969
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2970
  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2971
  ** through an intermediate state PENDING.   A PENDING lock prevents new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2972
  ** readers from attaching to the database but is unsufficient for us to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2973
  ** write.  The idea of a PENDING lock is to prevent new readers from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2974
  ** coming in while we wait for existing readers to clear.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2975
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2976
  ** While the pager is in the RESERVED state, the original database file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2977
  ** is unchanged and we can rollback without having to playback the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2978
  ** journal into the original database file.  Once we transition to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2979
  ** EXCLUSIVE, it means the database file has been changed and any rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2980
  ** will require a journal playback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2981
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2982
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2983
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2984
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2985
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2986
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2987
  pList = sort_pagelist(pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2988
  for(p=pList; p; p=p->pDirty){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2989
    assert( p->dirty );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2990
    p->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2991
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2992
  while( pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2993
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2994
    /* If the file has not yet been opened, open it now. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2995
    if( !pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2996
      assert(pPager->tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2997
      rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2998
                                pPager->vfsFlags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2999
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3000
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3001
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3002
    /* If there are dirty pages in the page cache with page numbers greater
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3003
    ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3004
    ** make the file smaller (presumably by auto-vacuum code). Do not write
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3005
    ** any such pages to the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3006
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3007
    if( pList->pgno<=pPager->dbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3008
      i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3009
      char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3010
      PAGERTRACE4("STORE %d page %d hash(%08x)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3011
                   PAGERID(pPager), pList->pgno, pager_pagehash(pList));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3012
      IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3013
      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3014
      PAGER_INCR(sqlite3_pager_writedb_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3015
      PAGER_INCR(pPager->nWrite);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3016
      if( pList->pgno==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3017
        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3018
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3019
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3020
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3021
    else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3022
      PAGERTRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3023
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3024
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3025
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3026
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3027
    pList->pageHash = pager_pagehash(pList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3028
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3029
    pList = pList->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3030
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3031
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3032
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3033
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3034
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3035
** Collect every dirty page into a dirty list and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3036
** return a pointer to the head of that list.  All pages are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3037
** collected even if they are still in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3038
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3039
static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3040
  return pPager->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3041
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3042
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3043
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3044
** Return TRUE if there is a hot journal on the given pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3045
** A hot journal is one that needs to be played back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3046
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3047
** If the current size of the database file is 0 but a journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3048
** exists, that is probably an old journal left over from a prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3049
** database with the same name.  Just delete the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3050
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3051
static int hasHotJournal(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3052
  sqlite3_vfs *pVfs = pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3053
  if( !pPager->useJournal ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3054
  if( !pPager->fd->isOpen ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3055
  if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3056
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3057
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3058
  if( sqlite3OsCheckReservedLock(pPager->fd) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3059
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3060
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3061
  if( sqlite3PagerPagecount(pPager)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3062
    sqlite3OsDelete(pVfs, pPager->zJournal, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3063
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3064
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3065
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3066
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3067
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3068
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3069
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3070
** Try to find a page in the cache that can be recycled. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3071
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3072
** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3073
** does not set the pPager->errCode variable.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3074
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3075
static int pager_recycle(Pager *pPager, PgHdr **ppPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3076
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3077
  *ppPg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3078
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3079
  /* It is illegal to call this function unless the pager object
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3080
  ** pointed to by pPager has at least one free page (page with nRef==0).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3081
  */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3082
  assert(!MEMDB);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3083
  assert(pPager->lru.pFirst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3084
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3085
  /* Find a page to recycle.  Try to locate a page that does not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3086
  ** require us to do an fsync() on the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3087
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3088
  pPg = pPager->lru.pFirstSynced;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3089
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3090
  /* If we could not find a page that does not require an fsync()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3091
  ** on the journal file then fsync the journal file.  This is a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3092
  ** very slow operation, so we work hard to avoid it.  But sometimes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3093
  ** it can't be helped.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3094
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3095
  if( pPg==0 && pPager->lru.pFirst){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3096
    int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3097
    int rc = syncJournal(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3098
    if( rc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3099
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3100
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3101
    if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3102
      /* If in full-sync mode, write a new journal header into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3103
      ** journal file. This is done to avoid ever modifying a journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3104
      ** header that is involved in the rollback of pages that have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3105
      ** already been written to the database (in case the header is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3106
      ** trashed when the nRec field is updated).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3107
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3108
      pPager->nRec = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3109
      assert( pPager->journalOff > 0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3110
      assert( pPager->doNotSync==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3111
      rc = writeJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3112
      if( rc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3113
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3114
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3115
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3116
    pPg = pPager->lru.pFirst;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3117
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3118
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3119
  assert( pPg->nRef==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3120
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3121
  /* Write the page to the database file if it is dirty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3122
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3123
  if( pPg->dirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3124
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3125
    assert( pPg->needSync==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3126
    makeClean(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3127
    pPg->dirty = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3128
    pPg->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3129
    rc = pager_write_pagelist( pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3130
    pPg->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3131
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3132
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3133
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3134
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3135
  assert( pPg->dirty==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3136
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3137
  /* If the page we are recycling is marked as alwaysRollback, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3138
  ** set the global alwaysRollback flag, thus disabling the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3139
  ** sqlite3PagerDontRollback() optimization for the rest of this transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3140
  ** It is necessary to do this because the page marked alwaysRollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3141
  ** might be reloaded at a later time but at that point we won't remember
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3142
  ** that is was marked alwaysRollback.  This means that all pages must
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3143
  ** be marked as alwaysRollback from here on out.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3144
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3145
  if( pPg->alwaysRollback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3146
    IOTRACE(("ALWAYS_ROLLBACK %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3147
    pPager->alwaysRollback = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3148
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3149
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3150
  /* Unlink the old page from the free list and the hash table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3151
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3152
  unlinkPage(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3153
  assert( pPg->pgno==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3154
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3155
  *ppPg = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3156
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3157
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3158
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3159
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3160
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3161
** This function is called to free superfluous dynamically allocated memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3162
** held by the pager system. Memory in use by any SQLite pager allocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3163
** by the current thread may be sqlite3_free()ed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3164
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3165
** nReq is the number of bytes of memory required. Once this much has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3166
** been released, the function returns. The return value is the total number 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3167
** of bytes of memory released.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3168
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3169
int sqlite3PagerReleaseMemory(int nReq){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3170
  int nReleased = 0;          /* Bytes of memory released so far */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3171
  sqlite3_mutex *mutex;       /* The MEM2 mutex */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3172
  Pager *pPager;              /* For looping over pagers */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3173
  BusyHandler *savedBusy;     /* Saved copy of the busy handler */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3174
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3175
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3176
  /* Acquire the memory-management mutex
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3177
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3178
  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3179
  sqlite3_mutex_enter(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3180
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3181
  /* Signal all database connections that memory management wants
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3182
  ** to have access to the pagers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3183
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3184
  for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3185
     pPager->iInUseMM = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3186
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3187
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3188
  while( rc==SQLITE_OK && (nReq<0 || nReleased<nReq) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3189
    PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3190
    PgHdr *pRecycled;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3191
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3192
    /* Try to find a page to recycle that does not require a sync(). If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3193
    ** this is not possible, find one that does require a sync().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3194
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3195
    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3196
    pPg = sqlite3LruPageList.pFirstSynced;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3197
    while( pPg && (pPg->needSync || pPg->pPager->iInUseDB) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3198
      pPg = pPg->gfree.pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3199
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3200
    if( !pPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3201
      pPg = sqlite3LruPageList.pFirst;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3202
      while( pPg && pPg->pPager->iInUseDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3203
        pPg = pPg->gfree.pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3204
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3205
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3206
    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3207
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3208
    /* If pPg==0, then the block above has failed to find a page to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3209
    ** recycle. In this case return early - no further memory will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3210
    ** be released.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3211
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3212
    if( !pPg ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3213
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3214
    pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3215
    assert(!pPg->needSync || pPg==pPager->lru.pFirst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3216
    assert(pPg->needSync || pPg==pPager->lru.pFirstSynced);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3217
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3218
    savedBusy = pPager->pBusyHandler;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3219
    pPager->pBusyHandler = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3220
    rc = pager_recycle(pPager, &pRecycled);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3221
    pPager->pBusyHandler = savedBusy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3222
    assert(pRecycled==pPg || rc!=SQLITE_OK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3223
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3224
      /* We've found a page to free. At this point the page has been 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3225
      ** removed from the page hash-table, free-list and synced-list 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3226
      ** (pFirstSynced). It is still in the all pages (pAll) list. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3227
      ** Remove it from this list before freeing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3228
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3229
      ** Todo: Check the Pager.pStmt list to make sure this is Ok. It 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3230
      ** probably is though.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3231
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3232
      PgHdr *pTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3233
      assert( pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3234
      if( pPg==pPager->pAll ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3235
         pPager->pAll = pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3236
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3237
        for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3238
        pTmp->pNextAll = pPg->pNextAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3239
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3240
      nReleased += (
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3241
          sizeof(*pPg) + pPager->pageSize
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3242
          + sizeof(u32) + pPager->nExtra
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3243
          + MEMDB*sizeof(PgHistory) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3244
      );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3245
      IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3246
      PAGER_INCR(sqlite3_pager_pgfree_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3247
      sqlite3_free(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3248
      pPager->nPage--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3249
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3250
      /* An error occured whilst writing to the database file or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3251
      ** journal in pager_recycle(). The error is not returned to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3252
      ** caller of this function. Instead, set the Pager.errCode variable.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3253
      ** The error will be returned to the user (or users, in the case 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3254
      ** of a shared pager cache) of the pager for which the error occured.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3255
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3256
      assert(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3257
          (rc&0xff)==SQLITE_IOERR ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3258
          rc==SQLITE_FULL ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3259
          rc==SQLITE_BUSY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3260
      );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3261
      assert( pPager->state>=PAGER_RESERVED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3262
      pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3263
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3265
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3266
  /* Clear the memory management flags and release the mutex
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3267
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3268
  for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3269
     pPager->iInUseMM = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3270
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3271
  sqlite3_mutex_leave(mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3272
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3273
  /* Return the number of bytes released
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3274
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3275
  return nReleased;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3276
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3277
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3278
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3279
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3280
** Read the content of page pPg out of the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3281
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3282
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3283
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3284
  i64 offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3285
  assert( MEMDB==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3286
  assert(pPager->fd->pMethods||pPager->tempFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3287
  if( !pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3288
    return SQLITE_IOERR_SHORT_READ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3289
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3290
  offset = (pgno-1)*(i64)pPager->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3291
  rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize, offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3292
  PAGER_INCR(sqlite3_pager_readdb_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3293
  PAGER_INCR(pPager->nRead);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3294
  IOTRACE(("PGIN %p %d\n", pPager, pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3295
  if( pgno==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3296
    memcpy(&pPager->dbFileVers, &((u8*)PGHDR_TO_DATA(pPg))[24],
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3297
                                              sizeof(pPager->dbFileVers));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3298
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3299
  CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3300
  PAGERTRACE4("FETCH %d page %d hash(%08x)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3301
               PAGERID(pPager), pPg->pgno, pager_pagehash(pPg));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3302
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3303
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3304
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3305
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3306
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3307
** This function is called to obtain the shared lock required before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3308
** data may be read from the pager cache. If the shared lock has already
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3309
** been obtained, this function is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3310
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3311
** Immediately after obtaining the shared lock (if required), this function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3312
** checks for a hot-journal file. If one is found, an emergency rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3313
** is performed immediately.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3314
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3315
static int pagerSharedLock(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3316
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3317
  int isHot = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3318
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3319
  /* If this database is opened for exclusive access, has no outstanding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3320
  ** page references and is in an error-state, now is the chance to clear
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3321
  ** the error. Discard the contents of the pager-cache and treat any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3322
  ** open journal file as a hot-journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3323
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3324
  if( !MEMDB && pPager->exclusiveMode && pPager->nRef==0 && pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3325
    if( pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3326
      isHot = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3327
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3328
    pager_reset(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3329
    pPager->errCode = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3330
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3331
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3332
  /* If the pager is still in an error state, do not proceed. The error 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3333
  ** state will be cleared at some point in the future when all page 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3334
  ** references are dropped and the cache can be discarded.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3335
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3336
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3337
    return pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3338
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3339
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3340
  if( pPager->state==PAGER_UNLOCK || isHot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3341
    sqlite3_vfs *pVfs = pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3342
    if( !MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3343
      assert( pPager->nRef==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3344
      if( !pPager->noReadlock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3345
        rc = pager_wait_on_lock(pPager, SHARED_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3346
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3347
          return pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3348
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3349
        assert( pPager->state>=SHARED_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3350
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3351
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3352
      /* If a journal file exists, and there is no RESERVED lock on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3353
      ** database file, then it either needs to be played back or deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3354
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3355
      if( hasHotJournal(pPager) || isHot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3356
        /* Get an EXCLUSIVE lock on the database file. At this point it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3357
        ** important that a RESERVED lock is not obtained on the way to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3358
        ** EXCLUSIVE lock. If it were, another process might open the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3359
        ** database file, detect the RESERVED lock, and conclude that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3360
        ** database is safe to read while this process is still rolling it 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3361
        ** back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3362
        ** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3363
        ** Because the intermediate RESERVED lock is not requested, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3364
        ** second process will get to this point in the code and fail to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3365
        ** obtain its own EXCLUSIVE lock on the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3366
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3367
        if( pPager->state<EXCLUSIVE_LOCK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3368
          rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3369
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3370
            pager_unlock(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3371
            return pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3372
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3373
          pPager->state = PAGER_EXCLUSIVE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3374
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3375
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3376
        /* Open the journal for reading only.  Return SQLITE_BUSY if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3377
        ** we are unable to open the journal file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3378
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3379
        ** The journal file does not need to be locked itself.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3380
        ** journal file is never open unless the main database file holds
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3381
        ** a write lock, so there is never any chance of two or more
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3382
        ** processes opening the journal at the same time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3383
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3384
        ** Open the journal for read/write access. This is because in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3385
        ** exclusive-access mode the file descriptor will be kept open and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3386
        ** possibly used for a transaction later on. On some systems, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3387
        ** OsTruncate() call used in exclusive-access mode also requires
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3388
        ** a read/write file handle.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3389
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3390
        if( !isHot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3391
          rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3392
          if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3393
            int fout = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3394
            int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3395
            assert( !pPager->tempFile );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3396
            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3397
            assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3398
            if( fout&SQLITE_OPEN_READONLY ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3399
              rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3400
              sqlite3OsClose(pPager->jfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3401
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3402
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3403
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3404
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3405
          pager_unlock(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3406
          return ((rc==SQLITE_NOMEM||rc==SQLITE_IOERR_NOMEM)?rc:SQLITE_BUSY);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3407
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3408
        pPager->journalOpen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3409
        pPager->journalStarted = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3410
        pPager->journalOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3411
        pPager->setMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3412
        pPager->journalHdr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3413
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3414
        /* Playback and delete the journal.  Drop the database write
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3415
        ** lock and reacquire the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3416
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3417
        rc = pager_playback(pPager, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3418
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3419
          return pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3420
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3421
        assert(pPager->state==PAGER_SHARED || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3422
            (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3423
        );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3424
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3425
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3426
      if( pPager->pAll ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3427
        /* The shared-lock has just been acquired on the database file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3428
        ** and there are already pages in the cache (from a previous
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3429
        ** read or write transaction).  Check to see if the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3430
        ** has been modified.  If the database has changed, flush the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3431
        ** cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3432
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3433
        ** Database changes is detected by looking at 15 bytes beginning
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3434
        ** at offset 24 into the file.  The first 4 of these 16 bytes are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3435
        ** a 32-bit counter that is incremented with each change.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3436
        ** other bytes change randomly with each file change when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3437
        ** a codec is in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3438
        ** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3439
        ** There is a vanishingly small chance that a change will not be 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3440
        ** detected.  The chance of an undetected change is so small that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3441
        ** it can be neglected.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3442
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3443
        char dbFileVers[sizeof(pPager->dbFileVers)];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3444
        sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3445
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3446
        if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3447
          return pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3448
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3449
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3450
        if( pPager->dbSize>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3451
          IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3452
          rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3453
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3454
            return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3455
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3456
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3457
          memset(dbFileVers, 0, sizeof(dbFileVers));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3458
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3459
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3460
        if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3461
          pager_reset(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3462
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3463
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3464
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3465
    assert( pPager->exclusiveMode || pPager->state<=PAGER_SHARED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3466
    if( pPager->state==PAGER_UNLOCK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3467
      pPager->state = PAGER_SHARED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3468
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3469
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3470
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3471
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3472
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3473
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3474
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3475
** Allocate a PgHdr object.   Either create a new one or reuse
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3476
** an existing one that is not otherwise in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3477
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3478
** A new PgHdr structure is created if any of the following are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3479
** true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3480
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3481
**     (1)  We have not exceeded our maximum allocated cache size
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3482
**          as set by the "PRAGMA cache_size" command.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3483
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3484
**     (2)  There are no unused PgHdr objects available at this time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3485
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3486
**     (3)  This is an in-memory database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3487
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3488
**     (4)  There are no PgHdr objects that do not require a journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3489
**          file sync and a sync of the journal file is currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3490
**          prohibited.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3491
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3492
** Otherwise, reuse an existing PgHdr.  In other words, reuse an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3493
** existing PgHdr if all of the following are true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3494
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3495
**     (1)  We have reached or exceeded the maximum cache size
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3496
**          allowed by "PRAGMA cache_size".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3497
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3498
**     (2)  There is a PgHdr available with PgHdr->nRef==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3499
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3500
**     (3)  We are not in an in-memory database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3501
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3502
**     (4)  Either there is an available PgHdr that does not need
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3503
**          to be synced to disk or else disk syncing is currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3504
**          allowed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3505
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3506
static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3507
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3508
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3509
  int nByteHdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3510
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3511
  /* Create a new PgHdr if any of the four conditions defined 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3512
  ** above are met: */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3513
  if( pPager->nPage<pPager->mxPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3514
   || pPager->lru.pFirst==0 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3515
   || MEMDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3516
   || (pPager->lru.pFirstSynced==0 && pPager->doNotSync)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3517
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3518
    if( pPager->nPage>=pPager->nHash ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3519
      pager_resize_hash_table(pPager,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3520
         pPager->nHash<256 ? 256 : pPager->nHash*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3521
      if( pPager->nHash==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3522
        rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3523
        goto pager_allocate_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3524
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3525
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3526
    pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3527
    nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3528
              + MEMDB*sizeof(PgHistory);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3529
    pPg = (PgHdr*)sqlite3_malloc( nByteHdr + pPager->pageSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3530
    pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3531
    if( pPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3532
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3533
      goto pager_allocate_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3534
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3535
    memset(pPg, 0, nByteHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3536
    pPg->pData = (void*)(nByteHdr + (char*)pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3537
    pPg->pPager = pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3538
    pPg->pNextAll = pPager->pAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3539
    pPager->pAll = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3540
    pPager->nPage++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3541
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3542
    /* Recycle an existing page with a zero ref-count. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3543
    rc = pager_recycle(pPager, &pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3544
    if( rc==SQLITE_BUSY ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3545
      rc = SQLITE_IOERR_BLOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3546
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3547
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3548
      goto pager_allocate_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3549
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3550
    assert( pPager->state>=SHARED_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3551
    assert(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3552
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3553
  *ppPg = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3554
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3555
pager_allocate_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3556
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3557
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3558
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3559
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3560
** Make sure we have the content for a page.  If the page was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3561
** previously acquired with noContent==1, then the content was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3562
** just initialized to zeros instead of being read from disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3563
** But now we need the real data off of disk.  So make sure we
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3564
** have it.  Read it in if we do not have it already.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3565
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3566
static int pager_get_content(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3567
  if( pPg->needRead ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3568
    int rc = readDbPage(pPg->pPager, pPg, pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3569
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3570
      pPg->needRead = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3571
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3572
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3573
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3574
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3575
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3576
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3577
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3578
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3579
** Acquire a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3580
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3581
** A read lock on the disk file is obtained when the first page is acquired. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3582
** This read lock is dropped when the last page is released.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3583
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3584
** This routine works for any page number greater than 0.  If the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3585
** file is smaller than the requested page, then no actual disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3586
** read occurs and the memory image of the page is initialized to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3587
** all zeros.  The extra data appended to a page is always initialized
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3588
** to zeros the first time a page is loaded into memory.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3589
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3590
** The acquisition might fail for several reasons.  In all cases,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3591
** an appropriate error code is returned and *ppPage is set to NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3592
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3593
** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3594
** to find a page in the in-memory cache first.  If the page is not already
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3595
** in memory, this routine goes to disk to read it in whereas Lookup()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3596
** just returns 0.  This routine acquires a read-lock the first time it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3597
** has to go to disk, and could also playback an old journal if necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3598
** Since Lookup() never goes to disk, it never has to deal with locks
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3599
** or journal files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3600
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3601
** If noContent is false, the page contents are actually read from disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3602
** If noContent is true, it means that we do not care about the contents
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3603
** of the page at this time, so do not do a disk read.  Just fill in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3604
** page content with zeros.  But mark the fact that we have not read the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3605
** content by setting the PgHdr.needRead flag.  Later on, if 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3606
** sqlite3PagerWrite() is called on this page or if this routine is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3607
** called again with noContent==0, that means that the content is needed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3608
** and the disk read should occur at that point.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3609
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3610
static int pagerAcquire(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3611
  Pager *pPager,      /* The pager open on the database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3612
  Pgno pgno,          /* Page number to fetch */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3613
  DbPage **ppPage,    /* Write a pointer to the page here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3614
  int noContent       /* Do not bother reading content from disk if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3615
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3616
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3617
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3618
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3619
  assert( pPager->state==PAGER_UNLOCK || pPager->nRef>0 || pgno==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3620
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3621
  /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3622
  ** number greater than this, or zero, is requested.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3623
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3624
  if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3625
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3626
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3627
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3628
  /* Make sure we have not hit any critical errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3629
  */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3630
  assert( pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3631
  *ppPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3632
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3633
  /* If this is the first page accessed, then get a SHARED lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3634
  ** on the database file. pagerSharedLock() is a no-op if 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3635
  ** a database lock is already held.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3636
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3637
  rc = pagerSharedLock(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3638
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3639
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3640
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3641
  assert( pPager->state!=PAGER_UNLOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3642
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3643
  pPg = pager_lookup(pPager, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3644
  if( pPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3645
    /* The requested page is not in the page cache. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3646
    int nMax;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3647
    int h;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3648
    PAGER_INCR(pPager->nMiss);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3649
    rc = pagerAllocatePage(pPager, &pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3650
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3651
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3652
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3653
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3654
    pPg->pgno = pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3655
    assert( !MEMDB || pgno>pPager->stmtSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3656
    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3657
#if 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3658
      sqlite3CheckMemory(pPager->aInJournal, pgno/8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3659
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3660
      assert( pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3661
      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3662
      pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3663
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3664
      pPg->inJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3665
      pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3666
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3667
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3668
    makeClean(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3669
    pPg->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3670
    REFINFO(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3671
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3672
    pPager->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3673
    if( pPager->nExtra>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3674
      memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3675
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3676
    nMax = sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3677
    if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3678
      rc = pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3679
      sqlite3PagerUnref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3680
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3681
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3682
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3683
    /* Populate the page with data, either by reading from the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3684
    ** file, or by setting the entire page to zero.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3685
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3686
    if( nMax<(int)pgno || MEMDB || (noContent && !pPager->alwaysRollback) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3687
      if( pgno>pPager->mxPgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3688
        sqlite3PagerUnref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3689
        return SQLITE_FULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3690
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3691
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3692
      pPg->needRead = noContent && !pPager->alwaysRollback;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3693
      IOTRACE(("ZERO %p %d\n", pPager, pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3694
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3695
      rc = readDbPage(pPager, pPg, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3696
      if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3697
        pPg->pgno = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3698
        sqlite3PagerUnref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3699
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3700
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3701
      pPg->needRead = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3702
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3703
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3704
    /* Link the page into the page hash table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3705
    h = pgno & (pPager->nHash-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3706
    assert( pgno!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3707
    pPg->pNextHash = pPager->aHash[h];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3708
    pPager->aHash[h] = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3709
    if( pPg->pNextHash ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3710
      assert( pPg->pNextHash->pPrevHash==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3711
      pPg->pNextHash->pPrevHash = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3712
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3713
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3714
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3715
    pPg->pageHash = pager_pagehash(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3716
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3717
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3718
    /* The requested page is in the page cache. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3719
    assert(pPager->nRef>0 || pgno==1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3720
    PAGER_INCR(pPager->nHit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3721
    if( !noContent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3722
      rc = pager_get_content(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3723
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3724
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3725
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3726
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3727
    page_ref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3728
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3729
  *ppPage = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3730
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3731
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3732
int sqlite3PagerAcquire(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3733
  Pager *pPager,      /* The pager open on the database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3734
  Pgno pgno,          /* Page number to fetch */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3735
  DbPage **ppPage,    /* Write a pointer to the page here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3736
  int noContent       /* Do not bother reading content from disk if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3737
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3738
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3739
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3740
  rc = pagerAcquire(pPager, pgno, ppPage, noContent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3741
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3742
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3743
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3744
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3745
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3746
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3747
** Acquire a page if it is already in the in-memory cache.  Do
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3748
** not read the page from disk.  Return a pointer to the page,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3749
** or 0 if the page is not in cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3750
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3751
** See also sqlite3PagerGet().  The difference between this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3752
** and sqlite3PagerGet() is that _get() will go to the disk and read
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3753
** in the page if the page is not already in cache.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3754
** returns NULL if the page is not in cache or if a disk I/O error 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3755
** has ever happened.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3756
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3757
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3758
  PgHdr *pPg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3759
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3760
  assert( pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3761
  assert( pgno!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3762
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3763
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3764
  if( pPager->state==PAGER_UNLOCK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3765
    assert( !pPager->pAll || pPager->exclusiveMode );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3766
  }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3767
    /* Do nothing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3768
  }else if( (pPg = pager_lookup(pPager, pgno))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3769
    page_ref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3770
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3771
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3772
  return pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3773
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3774
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3775
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3776
** Release a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3777
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3778
** If the number of references to the page drop to zero, then the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3779
** page is added to the LRU list.  When all references to all pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3780
** are released, a rollback occurs and the lock on the database is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3781
** removed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3782
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3783
int sqlite3PagerUnref(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3784
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3785
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3786
  /* Decrement the reference count for this page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3787
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3788
  assert( pPg->nRef>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3789
  pagerEnter(pPg->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3790
  pPg->nRef--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3791
  REFINFO(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3792
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3793
  CHECK_PAGE(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3795
  /* When the number of references to a page reach 0, call the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3796
  ** destructor and add the page to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3797
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3798
  if( pPg->nRef==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3799
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3800
    lruListAdd(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3801
    if( pPager->xDestructor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3802
      pPager->xDestructor(pPg, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3803
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3804
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3805
    /* When all pages reach the freelist, drop the read lock from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3806
    ** the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3807
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3808
    pPager->nRef--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3809
    assert( pPager->nRef>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3810
    if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3811
      pagerUnlockAndRollback(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3812
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3813
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3814
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3815
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3816
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3817
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3818
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3819
** Create a journal file for pPager.  There should already be a RESERVED
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3820
** or EXCLUSIVE lock on the database file when this routine is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3821
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3822
** Return SQLITE_OK if everything.  Return an error code and release the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3823
** write lock if anything goes wrong.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3824
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3825
static int pager_open_journal(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3826
  sqlite3_vfs *pVfs = pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3827
  int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3828
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3829
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3830
  assert( !MEMDB );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3831
  assert( pPager->state>=PAGER_RESERVED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3832
  assert( pPager->journalOpen==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3833
  assert( pPager->useJournal );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3834
  assert( pPager->aInJournal==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3835
  sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3836
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3837
  pPager->aInJournal = (u8*)sqlite3MallocZero( pPager->dbSize/8 + 1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3838
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3839
  if( pPager->aInJournal==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3840
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3841
    goto failed_to_open_journal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3842
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3843
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3844
  if( pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3845
    flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3846
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3847
    flags |= (SQLITE_OPEN_MAIN_JOURNAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3848
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3849
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3850
  rc = sqlite3JournalOpen(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3851
      pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3852
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3853
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3854
  rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3855
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3856
  assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3857
  pPager->journalOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3858
  pPager->setMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3859
  pPager->journalHdr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3860
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3861
    if( rc==SQLITE_NOMEM ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3862
      sqlite3OsDelete(pVfs, pPager->zJournal, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3863
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3864
    goto failed_to_open_journal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3865
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3866
  pPager->journalOpen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3867
  pPager->journalStarted = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3868
  pPager->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3869
  pPager->alwaysRollback = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3870
  pPager->nRec = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3871
  if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3872
    rc = pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3873
    goto failed_to_open_journal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3874
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3875
  pPager->origDbSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3876
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3877
  rc = writeJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3879
  if( pPager->stmtAutoopen && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3880
    rc = sqlite3PagerStmtBegin(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3881
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3882
  if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3883
    rc = pager_end_transaction(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3884
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3885
      rc = SQLITE_FULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3886
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3887
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3888
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3889
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3890
failed_to_open_journal:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3891
  sqlite3_free(pPager->aInJournal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3892
  pPager->aInJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3893
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3894
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3895
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3896
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3897
** Acquire a write-lock on the database.  The lock is removed when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3898
** the any of the following happen:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3899
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3900
**   *  sqlite3PagerCommitPhaseTwo() is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3901
**   *  sqlite3PagerRollback() is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3902
**   *  sqlite3PagerClose() is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3903
**   *  sqlite3PagerUnref() is called to on every outstanding page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3904
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3905
** The first parameter to this routine is a pointer to any open page of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3906
** database file.  Nothing changes about the page - it is used merely to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3907
** acquire a pointer to the Pager structure and as proof that there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3908
** already a read-lock on the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3909
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3910
** The second parameter indicates how much space in bytes to reserve for a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3911
** master journal file-name at the start of the journal when it is created.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3912
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3913
** A journal file is opened if this is not a temporary file.  For temporary
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3914
** files, the opening of the journal file is deferred until there is an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3915
** actual need to write to the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3916
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3917
** If the database is already reserved for writing, this routine is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3918
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3919
** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3920
** immediately instead of waiting until we try to flush the cache.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3921
** exFlag is ignored if a transaction is already active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3922
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3923
int sqlite3PagerBegin(DbPage *pPg, int exFlag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3924
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3925
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3926
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3927
  assert( pPg->nRef>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3928
  assert( pPager->state!=PAGER_UNLOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3929
  if( pPager->state==PAGER_SHARED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3930
    assert( pPager->aInJournal==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3931
    if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3932
      pPager->state = PAGER_EXCLUSIVE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3933
      pPager->origDbSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3934
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3935
      rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3936
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3937
        pPager->state = PAGER_RESERVED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3938
        if( exFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3939
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3940
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3941
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3942
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3943
        pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3944
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3945
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3946
      pPager->dirtyCache = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3947
      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3948
      if( pPager->useJournal && !pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3949
        rc = pager_open_journal(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3950
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3951
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3952
  }else if( pPager->journalOpen && pPager->journalOff==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3953
    /* This happens when the pager was in exclusive-access mode last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3954
    ** time a (read or write) transaction was successfully concluded
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3955
    ** by this connection. Instead of deleting the journal file it was 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3956
    ** kept open and truncated to 0 bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3957
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3958
    assert( pPager->nRec==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3959
    assert( pPager->origDbSize==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3960
    assert( pPager->aInJournal==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3961
    sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3962
    pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3963
    pPager->aInJournal = (u8*)sqlite3MallocZero( pPager->dbSize/8 + 1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3964
    pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3965
    if( !pPager->aInJournal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3966
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3967
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3968
      pPager->origDbSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3969
      rc = writeJournalHdr(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3971
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3972
  assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3973
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3974
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3975
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3976
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3977
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3978
** Make a page dirty.  Set its dirty flag and add it to the dirty
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3979
** page list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3980
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3981
static void makeDirty(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3982
  if( pPg->dirty==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3983
    Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3984
    pPg->dirty = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3985
    pPg->pDirty = pPager->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3986
    if( pPager->pDirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3987
      pPager->pDirty->pPrevDirty = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3988
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3989
    pPg->pPrevDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3990
    pPager->pDirty = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3991
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3992
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3993
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3994
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3995
** Make a page clean.  Clear its dirty bit and remove it from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3996
** dirty page list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3997
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3998
static void makeClean(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3999
  if( pPg->dirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4000
    pPg->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4001
    if( pPg->pDirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4002
      assert( pPg->pDirty->pPrevDirty==pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4003
      pPg->pDirty->pPrevDirty = pPg->pPrevDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4004
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4005
    if( pPg->pPrevDirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4006
      assert( pPg->pPrevDirty->pDirty==pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4007
      pPg->pPrevDirty->pDirty = pPg->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4008
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4009
      assert( pPg->pPager->pDirty==pPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4010
      pPg->pPager->pDirty = pPg->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4011
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4012
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4013
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4014
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4015
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4016
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4017
** Mark a data page as writeable.  The page is written into the journal 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4018
** if it is not there already.  This routine must be called before making
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4019
** changes to a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4020
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4021
** The first time this routine is called, the pager creates a new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4022
** journal and acquires a RESERVED lock on the database.  If the RESERVED
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4023
** lock could not be acquired, this routine returns SQLITE_BUSY.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4024
** calling routine must check for that return value and be careful not to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4025
** change any page data until this routine returns SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4026
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4027
** If the journal file could not be written because the disk is full,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4028
** then this routine returns SQLITE_FULL and does an immediate rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4029
** All subsequent write attempts also return SQLITE_FULL until there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4030
** is a call to sqlite3PagerCommit() or sqlite3PagerRollback() to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4031
** reset.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4032
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4033
static int pager_write(PgHdr *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4034
  void *pData = PGHDR_TO_DATA(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4035
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4036
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4037
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4038
  /* Check for errors
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4039
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4040
  if( pPager->errCode ){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4041
    return pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4042
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4043
  if( pPager->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4044
    return SQLITE_PERM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4045
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4046
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4047
  assert( !pPager->setMaster );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4048
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4049
  CHECK_PAGE(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4050
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4051
  /* If this page was previously acquired with noContent==1, that means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4052
  ** we didn't really read in the content of the page.  This can happen
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4053
  ** (for example) when the page is being moved to the freelist.  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4054
  ** now we are (perhaps) moving the page off of the freelist for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4055
  ** reuse and we need to know its original content so that content
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4056
  ** can be stored in the rollback journal.  So do the read at this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4057
  ** time.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4058
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4059
  rc = pager_get_content(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4060
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4061
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4062
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4063
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4064
  /* Mark the page as dirty.  If the page has already been written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4065
  ** to the journal then we can return right away.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4066
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4067
  makeDirty(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4068
  if( pPg->inJournal && (pageInStatement(pPg) || pPager->stmtInUse==0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4069
    pPager->dirtyCache = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4070
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4071
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4072
    /* If we get this far, it means that the page needs to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4073
    ** written to the transaction journal or the ckeckpoint journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4074
    ** or both.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4075
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4076
    ** First check to see that the transaction journal exists and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4077
    ** create it if it does not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4078
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4079
    assert( pPager->state!=PAGER_UNLOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4080
    rc = sqlite3PagerBegin(pPg, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4081
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4082
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4083
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4084
    assert( pPager->state>=PAGER_RESERVED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4085
    if( !pPager->journalOpen && pPager->useJournal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4086
      rc = pager_open_journal(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4087
      if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4088
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4089
    assert( pPager->journalOpen || !pPager->useJournal );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4090
    pPager->dirtyCache = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4091
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4092
    /* The transaction journal now exists and we have a RESERVED or an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4093
    ** EXCLUSIVE lock on the main database file.  Write the current page to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4094
    ** the transaction journal if it is not there already.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4095
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4096
    if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4097
      if( (int)pPg->pgno <= pPager->origDbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4098
        if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4099
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4100
          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4101
          assert( pHist->pOrig==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4102
          pHist->pOrig = (u8*)sqlite3_malloc( pPager->pageSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4103
          if( !pHist->pOrig ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4104
            return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4105
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4106
          memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4107
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4108
          u32 cksum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4109
          char *pData2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4111
          /* We should never write to the journal file the page that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4112
          ** contains the database locks.  The following assert verifies
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4113
          ** that we do not. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4114
          assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4115
          pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4116
          cksum = pager_cksum(pPager, (u8*)pData2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4117
          rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4118
          if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4119
            rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4120
                                pPager->journalOff + 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4121
            pPager->journalOff += pPager->pageSize+4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4122
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4123
          if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4124
            rc = write32bits(pPager->jfd, pPager->journalOff, cksum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4125
            pPager->journalOff += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4126
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4127
          IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4128
                   pPager->journalOff, pPager->pageSize));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4129
          PAGER_INCR(sqlite3_pager_writej_count);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4130
          PAGERTRACE5("JOURNAL %d page %d needSync=%d hash(%08x)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4131
               PAGERID(pPager), pPg->pgno, pPg->needSync, pager_pagehash(pPg));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4132
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4133
          /* An error has occured writing to the journal file. The 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4134
          ** transaction will be rolled back by the layer above.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4135
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4136
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4137
            return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4138
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4139
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4140
          pPager->nRec++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4141
          assert( pPager->aInJournal!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4142
          pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4143
          pPg->needSync = !pPager->noSync;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4144
          if( pPager->stmtInUse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4145
            pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4146
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4147
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4148
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4149
        pPg->needSync = !pPager->journalStarted && !pPager->noSync;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4150
        PAGERTRACE4("APPEND %d page %d needSync=%d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4151
                PAGERID(pPager), pPg->pgno, pPg->needSync);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4152
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4153
      if( pPg->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4154
        pPager->needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4155
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4156
      pPg->inJournal = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4157
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4158
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4159
    /* If the statement journal is open and the page is not in it,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4160
    ** then write the current page to the statement journal.  Note that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4161
    ** the statement journal format differs from the standard journal format
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4162
    ** in that it omits the checksums and the header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4163
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4164
    if( pPager->stmtInUse 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4165
     && !pageInStatement(pPg) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4166
     && (int)pPg->pgno<=pPager->stmtSize 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4167
    ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4168
      assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4169
      if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4170
        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4171
        assert( pHist->pStmt==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4172
        pHist->pStmt = (u8*)sqlite3_malloc( pPager->pageSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4173
        if( pHist->pStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4174
          memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4175
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4176
        PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4177
        page_add_to_stmt_list(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4178
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4179
        i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4180
        char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4181
        rc = write32bits(pPager->stfd, offset, pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4182
        if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4183
          rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4184
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4185
        PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4186
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4187
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4188
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4189
        pPager->stmtNRec++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4190
        assert( pPager->aInStmt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4191
        pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4192
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4193
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4194
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4196
  /* Update the database size and return.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4197
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4198
  assert( pPager->state>=PAGER_SHARED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4199
  if( pPager->dbSize<(int)pPg->pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4200
    pPager->dbSize = pPg->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4201
    if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4202
      pPager->dbSize++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4203
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4204
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4205
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4206
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4207
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4208
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4209
** This function is used to mark a data-page as writable. It uses 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4210
** pager_write() to open a journal file (if it is not already open)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4211
** and write the page *pData to the journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4212
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4213
** The difference between this function and pager_write() is that this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4214
** function also deals with the special case where 2 or more pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4215
** fit on a single disk sector. In this case all co-resident pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4216
** must have been written to the journal file before returning.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4217
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4218
int sqlite3PagerWrite(DbPage *pDbPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4219
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4220
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4221
  PgHdr *pPg = pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4222
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4223
  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4224
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4225
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4226
  if( !MEMDB && nPagePerSector>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4227
    Pgno nPageCount;          /* Total number of pages in database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4228
    Pgno pg1;                 /* First page of the sector pPg is located on. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4229
    int nPage;                /* Number of pages starting at pg1 to journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4230
    int ii;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4231
    int needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4232
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4233
    /* Set the doNotSync flag to 1. This is because we cannot allow a journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4234
    ** header to be written between the pages journaled by this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4235
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4236
    assert( pPager->doNotSync==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4237
    pPager->doNotSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4238
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4239
    /* This trick assumes that both the page-size and sector-size are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4240
    ** an integer power of 2. It sets variable pg1 to the identifier
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4241
    ** of the first page of the sector pPg is located on.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4242
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4243
    pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4244
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4245
    nPageCount = sqlite3PagerPagecount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4246
    if( pPg->pgno>nPageCount ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4247
      nPage = (pPg->pgno - pg1)+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4248
    }else if( (pg1+nPagePerSector-1)>nPageCount ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4249
      nPage = nPageCount+1-pg1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4250
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4251
      nPage = nPagePerSector;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4252
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4253
    assert(nPage>0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4254
    assert(pg1<=pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4255
    assert((pg1+nPage)>pPg->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4256
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4257
    for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4258
      Pgno pg = pg1+ii;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4259
      PgHdr *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4260
      if( !pPager->aInJournal || pg==pPg->pgno || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4261
          pg>pPager->origDbSize || !(pPager->aInJournal[pg/8]&(1<<(pg&7)))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4262
      ) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4263
        if( pg!=PAGER_MJ_PGNO(pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4264
          rc = sqlite3PagerGet(pPager, pg, &pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4265
          if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4266
            rc = pager_write(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4267
            if( pPage->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4268
              needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4269
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4270
            sqlite3PagerUnref(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4271
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4272
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4273
      }else if( (pPage = pager_lookup(pPager, pg)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4274
        if( pPage->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4275
          needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4276
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4277
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4278
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4279
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4280
    /* If the PgHdr.needSync flag is set for any of the nPage pages 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4281
    ** starting at pg1, then it needs to be set for all of them. Because
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4282
    ** writing to any of these nPage pages may damage the others, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4283
    ** journal file must contain sync()ed copies of all of them
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4284
    ** before any of them can be written out to the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4285
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4286
    if( needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4287
      for(ii=0; ii<nPage && needSync; ii++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4288
        PgHdr *pPage = pager_lookup(pPager, pg1+ii);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4289
        if( pPage ) pPage->needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4290
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4291
      assert(pPager->needSync);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4292
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4293
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4294
    assert( pPager->doNotSync==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4295
    pPager->doNotSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4296
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4297
    rc = pager_write(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4298
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4299
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4300
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4301
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4302
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4303
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4304
** Return TRUE if the page given in the argument was previously passed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4305
** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4306
** to change the content of the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4307
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4308
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4309
int sqlite3PagerIswriteable(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4310
  return pPg->dirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4311
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4312
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4313
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4314
#ifndef SQLITE_OMIT_VACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4316
** Replace the content of a single page with the information in the third
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4317
** argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4318
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4319
int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void *pData){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4320
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4321
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4322
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4323
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4324
  rc = sqlite3PagerGet(pPager, pgno, &pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4325
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4326
    rc = sqlite3PagerWrite(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4327
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4328
      memcpy(sqlite3PagerGetData(pPg), pData, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4329
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4330
    sqlite3PagerUnref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4331
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4332
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4333
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4334
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4335
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4336
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4337
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4338
** A call to this routine tells the pager that it is not necessary to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4339
** write the information on page pPg back to the disk, even though
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4340
** that page might be marked as dirty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4341
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4342
** The overlying software layer calls this routine when all of the data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4343
** on the given page is unused.  The pager marks the page as clean so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4344
** that it does not get written to disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4345
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4346
** Tests show that this optimization, together with the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4347
** sqlite3PagerDontRollback() below, more than double the speed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4348
** of large INSERT operations and quadruple the speed of large DELETEs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4349
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4350
** When this routine is called, set the alwaysRollback flag to true.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4351
** Subsequent calls to sqlite3PagerDontRollback() for the same page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4352
** will thereafter be ignored.  This is necessary to avoid a problem
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4353
** where a page with data is added to the freelist during one part of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4354
** a transaction then removed from the freelist during a later part
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4355
** of the same transaction and reused for some other purpose.  When it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4356
** is first added to the freelist, this routine is called.  When reused,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4357
** the sqlite3PagerDontRollback() routine is called.  But because the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4358
** page contains critical data, we still need to be sure it gets
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4359
** rolled back in spite of the sqlite3PagerDontRollback() call.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4360
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4361
void sqlite3PagerDontWrite(DbPage *pDbPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4362
  PgHdr *pPg = pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4363
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4364
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4365
  if( MEMDB ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4366
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4367
  pPg->alwaysRollback = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4368
  if( pPg->dirty && !pPager->stmtInUse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4369
    assert( pPager->state>=PAGER_SHARED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4370
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4371
      /* If this pages is the last page in the file and the file has grown
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4372
      ** during the current transaction, then do NOT mark the page as clean.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4373
      ** When the database file grows, we must make sure that the last page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4374
      ** gets written at least once so that the disk file will be the correct
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4375
      ** size. If you do not write this page and the size of the file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4376
      ** on the disk ends up being too small, that can lead to database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4377
      ** corruption during the next transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4378
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4379
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4380
      PAGERTRACE3("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4381
      IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4382
      makeClean(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4383
#ifdef SQLITE_CHECK_PAGES
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4384
      pPg->pageHash = pager_pagehash(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4385
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4386
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4387
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4388
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4389
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4390
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4391
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4392
** A call to this routine tells the pager that if a rollback occurs,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4393
** it is not necessary to restore the data on the given page.  This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4394
** means that the pager does not have to record the given page in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4395
** rollback journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4396
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4397
** If we have not yet actually read the content of this page (if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4398
** the PgHdr.needRead flag is set) then this routine acts as a promise
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4399
** that we will never need to read the page content in the future.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4400
** so the needRead flag can be cleared at this point.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4401
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4402
void sqlite3PagerDontRollback(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4403
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4404
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4405
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4406
  assert( pPager->state>=PAGER_RESERVED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4407
  if( pPager->journalOpen==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4408
  if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4409
  if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4410
    assert( pPager->aInJournal!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4411
    pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4412
    pPg->inJournal = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4413
    pPg->needRead = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4414
    if( pPager->stmtInUse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4415
      pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4416
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4417
    PAGERTRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4418
    IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4419
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4420
  if( pPager->stmtInUse 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4421
   && !pageInStatement(pPg) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4422
   && (int)pPg->pgno<=pPager->stmtSize 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4423
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4424
    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4425
    assert( pPager->aInStmt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4426
    pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4427
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4428
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4429
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4430
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4431
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4432
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4433
** This routine is called to increment the database file change-counter,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4434
** stored at byte 24 of the pager file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4435
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4436
static int pager_incr_changecounter(Pager *pPager, int isDirect){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4437
  PgHdr *pPgHdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4438
  u32 change_counter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4439
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4440
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4441
  if( !pPager->changeCountDone ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4442
    /* Open page 1 of the file for writing. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4443
    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4444
    if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4445
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4446
    if( !isDirect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4447
      rc = sqlite3PagerWrite(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4448
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4449
        sqlite3PagerUnref(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4450
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4451
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4452
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4453
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4454
    /* Increment the value just read and write it back to byte 24. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4455
    change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4456
    change_counter++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4457
    put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4458
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4459
    if( isDirect && pPager->fd->isOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4460
      const void *zBuf = PGHDR_TO_DATA(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4461
      rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4462
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4463
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4464
    /* Release the page reference. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4465
    sqlite3PagerUnref(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4466
    pPager->changeCountDone = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4467
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4468
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4469
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4470
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4471
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4472
** Sync the database file for the pager pPager. zMaster points to the name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4473
** of a master journal file that should be written into the individual
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4474
** journal file. zMaster may be NULL, which is interpreted as no master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4475
** journal (a single database transaction).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4476
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4477
** This routine ensures that the journal is synced, all dirty pages written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4478
** to the database file and the database file synced. The only thing that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4479
** remains to commit the transaction is to delete the journal file (or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4480
** master journal file if specified).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4481
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4482
** Note that if zMaster==NULL, this does not overwrite a previous value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4483
** passed to an sqlite3PagerCommitPhaseOne() call.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4484
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4485
** If parameter nTrunc is non-zero, then the pager file is truncated to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4486
** nTrunc pages (this is used by auto-vacuum databases).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4487
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4488
int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4489
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4490
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4491
  PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4492
      pPager->zFilename, zMaster, nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4493
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4494
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4495
  /* If this is an in-memory db, or no pages have been written to, or this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4496
  ** function has already been called, it is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4497
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4498
  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4499
    PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4500
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4501
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4502
    /* The atomic-write optimization can be used if all of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4503
    ** following are true:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4504
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4505
    **    + The file-system supports the atomic-write property for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4506
    **      blocks of size page-size, and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4507
    **    + This commit is not part of a multi-file transaction, and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4508
    **    + Exactly one page has been modified and store in the journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4509
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4510
    ** If the optimization can be used, then the journal file will never
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4511
    ** be created for this transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4512
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4513
    int useAtomicWrite = (
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4514
        !zMaster && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4515
        pPager->journalOff==jrnlBufferSize(pPager) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4516
        nTrunc==0 && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4517
        (0==pPager->pDirty || 0==pPager->pDirty->pDirty)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4518
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4519
    if( useAtomicWrite ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4520
      /* Update the nRec field in the journal file. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4521
      int offset = pPager->journalHdr + sizeof(aJournalMagic);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4522
      assert(pPager->nRec==1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4523
      rc = write32bits(pPager->jfd, offset, pPager->nRec);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4524
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4525
      /* Update the db file change counter. The following call will modify
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4526
      ** the in-memory representation of page 1 to include the updated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4527
      ** change counter and then write page 1 directly to the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4528
      ** file. Because of the atomic-write property of the host file-system, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4529
      ** this is safe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4530
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4531
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4532
        rc = pager_incr_changecounter(pPager, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4533
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4534
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4535
      rc = sqlite3JournalCreate(pPager->jfd);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4536
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4537
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4538
    if( !useAtomicWrite && rc==SQLITE_OK )
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4539
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4540
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4541
    /* If a master journal file name has already been written to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4542
    ** journal file, then no sync is required. This happens when it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4543
    ** written, then the process fails to upgrade from a RESERVED to an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4544
    ** EXCLUSIVE lock. The next time the process tries to commit the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4545
    ** transaction the m-j name will have already been written.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4546
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4547
    if( !pPager->setMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4548
      assert( pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4549
      rc = pager_incr_changecounter(pPager, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4550
      if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4551
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4552
      if( nTrunc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4553
        /* If this transaction has made the database smaller, then all pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4554
        ** being discarded by the truncation must be written to the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4555
        ** file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4556
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4557
        Pgno i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4558
        int iSkip = PAGER_MJ_PGNO(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4559
        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4560
          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4561
            rc = sqlite3PagerGet(pPager, i, &pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4562
            if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4563
            rc = sqlite3PagerWrite(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4564
            sqlite3PagerUnref(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4565
            if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4566
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4567
        } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4568
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4569
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4570
      rc = writeMasterJournal(pPager, zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4571
      if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4572
      rc = syncJournal(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4573
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4574
    if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4575
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4576
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4577
    if( nTrunc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4578
      rc = sqlite3PagerTruncate(pPager, nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4579
      if( rc!=SQLITE_OK ) goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4580
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4581
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4583
    /* Write all dirty pages to the database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4584
    pPg = pager_get_all_dirty_pages(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4585
    rc = pager_write_pagelist(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4586
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4587
      while( pPg && !pPg->dirty ){ pPg = pPg->pDirty; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4588
      pPager->pDirty = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4589
      goto sync_exit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4590
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4591
    pPager->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4592
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4593
    /* Sync the database file. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4594
    if( !pPager->noSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4595
      rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4596
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4597
    IOTRACE(("DBSYNC %p\n", pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4598
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4599
    pPager->state = PAGER_SYNCED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4600
  }else if( MEMDB && nTrunc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4601
    rc = sqlite3PagerTruncate(pPager, nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4602
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4603
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4604
sync_exit:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4605
  if( rc==SQLITE_IOERR_BLOCKED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4606
    /* pager_incr_changecounter() may attempt to obtain an exclusive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4607
     * lock to spill the cache and return IOERR_BLOCKED. But since 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4608
     * there is no chance the cache is inconsistent, it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4609
     * better to return SQLITE_BUSY.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4610
     */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4611
    rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4612
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4613
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4614
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4615
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4616
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4617
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4618
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4619
** Commit all changes to the database and release the write lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4620
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4621
** If the commit fails for any reason, a rollback attempt is made
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4622
** and an error code is returned.  If the commit worked, SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4623
** is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4624
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4625
int sqlite3PagerCommitPhaseTwo(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4626
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4627
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4628
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4629
  if( pPager->errCode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4630
    return pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4631
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4632
  if( pPager->state<PAGER_RESERVED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4633
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4634
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4635
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4636
  PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4637
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4638
    pPg = pager_get_all_dirty_pages(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4639
    while( pPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4640
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4641
      clearHistory(pHist);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4642
      pPg->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4643
      pPg->inJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4644
      pHist->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4645
      pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4646
      pHist->pPrevStmt = pHist->pNextStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4647
      pPg = pPg->pDirty;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4648
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4649
    pPager->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4650
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4651
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4652
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4653
      assert( !pPg->alwaysRollback );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4654
      assert( !pHist->pOrig );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4655
      assert( !pHist->pStmt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4656
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4657
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4658
    pPager->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4659
    pPager->state = PAGER_SHARED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4660
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4661
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4662
  assert( pPager->journalOpen || !pPager->dirtyCache );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4663
  assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4664
  rc = pager_end_transaction(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4665
  rc = pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4666
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4667
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4668
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4669
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4670
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4671
** Rollback all changes.  The database falls back to PAGER_SHARED mode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4672
** All in-memory cache pages revert to their original data contents.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4673
** The journal is deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4674
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4675
** This routine cannot fail unless some other process is not following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4676
** the correct locking protocol or unless some other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4677
** process is writing trash into the journal file (SQLITE_CORRUPT) or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4678
** unless a prior malloc() failed (SQLITE_NOMEM).  Appropriate error
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4679
** codes are returned for all these occasions.  Otherwise,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4680
** SQLITE_OK is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4681
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4682
int sqlite3PagerRollback(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4683
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4684
  PAGERTRACE2("ROLLBACK %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4685
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4686
    PgHdr *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4687
    for(p=pPager->pAll; p; p=p->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4688
      PgHistory *pHist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4689
      assert( !p->alwaysRollback );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4690
      if( !p->dirty ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4691
        assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pOrig );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4692
        assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pStmt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4693
        continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4694
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4695
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4696
      pHist = PGHDR_TO_HIST(p, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4697
      if( pHist->pOrig ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4698
        memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4699
        PAGERTRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4700
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4701
        PAGERTRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4702
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4703
      clearHistory(pHist);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4704
      p->dirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4705
      p->inJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4706
      pHist->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4707
      pHist->pPrevStmt = pHist->pNextStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4708
      if( pPager->xReiniter ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4709
        pPager->xReiniter(p, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4710
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4711
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4712
    pPager->pDirty = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4713
    pPager->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4714
    pPager->dbSize = pPager->origDbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4715
    pager_truncate_cache(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4716
    pPager->stmtInUse = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4717
    pPager->state = PAGER_SHARED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4718
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4719
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4720
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4721
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4722
  if( !pPager->dirtyCache || !pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4723
    rc = pager_end_transaction(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4724
    pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4725
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4726
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4727
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4728
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4729
    if( pPager->state>=PAGER_EXCLUSIVE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4730
      pager_playback(pPager, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4731
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4732
    pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4733
    return pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4734
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4735
  if( pPager->state==PAGER_RESERVED ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4736
    int rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4737
    rc = pager_playback(pPager, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4738
    rc2 = pager_end_transaction(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4739
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4740
      rc = rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4741
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4742
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4743
    rc = pager_playback(pPager, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4744
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4745
  /* pager_reset(pPager); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4746
  pPager->dbSize = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4747
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4748
  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4749
  ** cache. So call pager_error() on the way out to make any error 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4750
  ** persistent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4751
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4752
  rc = pager_error(pPager, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4753
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4754
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4755
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4756
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4757
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4758
** Return TRUE if the database file is opened read-only.  Return FALSE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4759
** if the database is (in theory) writable.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4760
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4761
int sqlite3PagerIsreadonly(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4762
  return pPager->readOnly;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4763
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4764
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4765
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4766
** Return the number of references to the pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4767
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4768
int sqlite3PagerRefcount(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4769
  return pPager->nRef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4770
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4771
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4772
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4773
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4774
** This routine is used for testing and analysis only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4775
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4776
int *sqlite3PagerStats(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4777
  static int a[11];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4778
  a[0] = pPager->nRef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4779
  a[1] = pPager->nPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4780
  a[2] = pPager->mxPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4781
  a[3] = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4782
  a[4] = pPager->state;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4783
  a[5] = pPager->errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4784
  a[6] = pPager->nHit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4785
  a[7] = pPager->nMiss;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4786
  a[8] = 0;  /* Used to be pPager->nOvfl */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4787
  a[9] = pPager->nRead;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4788
  a[10] = pPager->nWrite;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4789
  return a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4790
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4791
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4792
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4793
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4794
** Set the statement rollback point.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4795
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4796
** This routine should be called with the transaction journal already
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4797
** open.  A new statement journal is created that can be used to rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4798
** changes of a single SQL command within a larger transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4799
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4800
static int pagerStmtBegin(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4801
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4802
  assert( !pPager->stmtInUse );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4803
  assert( pPager->state>=PAGER_SHARED );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4804
  assert( pPager->dbSize>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4805
  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4806
  if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4807
    pPager->stmtInUse = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4808
    pPager->stmtSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4809
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4810
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4811
  if( !pPager->journalOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4812
    pPager->stmtAutoopen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4813
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4814
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4815
  assert( pPager->journalOpen );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4816
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4817
  assert( pPager->aInStmt==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4818
  pPager->aInStmt = (u8*)sqlite3MallocZero( pPager->dbSize/8 + 1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4819
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4820
  if( pPager->aInStmt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4821
    /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4822
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4823
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4824
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4825
  rc = sqlite3OsFileSize(pPager->jfd, &pPager->stmtJSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4826
  if( rc ) goto stmt_begin_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4827
  assert( pPager->stmtJSize == pPager->journalOff );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4828
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4829
  pPager->stmtJSize = pPager->journalOff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4830
  pPager->stmtSize = pPager->dbSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4831
  pPager->stmtHdrOff = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4832
  pPager->stmtCksum = pPager->cksumInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4833
  if( !pPager->stmtOpen ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4834
    rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, pPager->zStmtJrnl,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4835
                              SQLITE_OPEN_SUBJOURNAL);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4836
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4837
      goto stmt_begin_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4838
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4839
    pPager->stmtOpen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4840
    pPager->stmtNRec = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4841
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4842
  pPager->stmtInUse = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4843
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4844
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4845
stmt_begin_failed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4846
  if( pPager->aInStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4847
    sqlite3_free(pPager->aInStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4848
    pPager->aInStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4849
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4850
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4851
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4852
int sqlite3PagerStmtBegin(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4853
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4854
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4855
  rc = pagerStmtBegin(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4856
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4857
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4858
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4859
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4860
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4861
** Commit a statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4862
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4863
int sqlite3PagerStmtCommit(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4864
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4865
  if( pPager->stmtInUse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4866
    PgHdr *pPg, *pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4867
    PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4868
    if( !MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4869
      /* sqlite3OsTruncate(pPager->stfd, 0); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4870
      sqlite3_free( pPager->aInStmt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4871
      pPager->aInStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4872
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4873
      for(pPg=pPager->pStmt; pPg; pPg=pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4874
        PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4875
        pNext = pHist->pNextStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4876
        assert( pHist->inStmt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4877
        pHist->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4878
        pHist->pPrevStmt = pHist->pNextStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4879
        sqlite3_free(pHist->pStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4880
        pHist->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4881
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4882
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4883
    pPager->stmtNRec = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4884
    pPager->stmtInUse = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4885
    pPager->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4886
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4887
  pPager->stmtAutoopen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4888
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4889
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4890
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4891
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4892
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4893
** Rollback a statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4894
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4895
int sqlite3PagerStmtRollback(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4896
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4897
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4898
  if( pPager->stmtInUse ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4899
    PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4900
    if( MEMDB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4901
      PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4902
      PgHistory *pHist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4903
      for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4904
        pHist = PGHDR_TO_HIST(pPg, pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4905
        if( pHist->pStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4906
          memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4907
          sqlite3_free(pHist->pStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4908
          pHist->pStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4909
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4910
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4911
      pPager->dbSize = pPager->stmtSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4912
      pager_truncate_cache(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4913
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4914
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4915
      rc = pager_stmt_playback(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4916
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4917
    sqlite3PagerStmtCommit(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4918
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4919
    rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4920
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4921
  pPager->stmtAutoopen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4922
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4923
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4924
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4925
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4926
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4927
** Return the full pathname of the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4928
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4929
const char *sqlite3PagerFilename(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4930
  return pPager->zFilename;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4931
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4932
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4933
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4934
** Return the VFS structure for the pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4935
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4936
const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4937
  return pPager->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4938
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4939
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4940
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4941
** Return the file handle for the database file associated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4942
** with the pager.  This might return NULL if the file has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4943
** not yet been opened.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4944
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4945
sqlite3_file *sqlite3PagerFile(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4946
  return pPager->fd;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4947
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4948
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4949
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4950
** Return the directory of the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4951
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4952
const char *sqlite3PagerDirname(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4953
  return pPager->zDirectory;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4954
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4955
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4956
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4957
** Return the full pathname of the journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4958
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4959
const char *sqlite3PagerJournalname(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4960
  return pPager->zJournal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4961
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4962
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4963
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4964
** Return true if fsync() calls are disabled for this pager.  Return FALSE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4965
** if fsync()s are executed normally.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4966
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4967
int sqlite3PagerNosync(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4968
  return pPager->noSync;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4969
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4970
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4971
#ifdef SQLITE_HAS_CODEC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4972
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4973
** Set the codec for this pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4974
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4975
void sqlite3PagerSetCodec(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4976
  Pager *pPager,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4977
  void *(*xCodec)(void*,void*,Pgno,int),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4978
  void *pCodecArg
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4979
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4980
  pPager->xCodec = xCodec;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4981
  pPager->pCodecArg = pCodecArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4982
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4983
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4984
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4985
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4986
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4987
** Move the page pPg to location pgno in the file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4988
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4989
** There must be no references to the page previously located at
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4990
** pgno (which we call pPgOld) though that page is allowed to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4991
** in cache.  If the page previous located at pgno is not already
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4992
** in the rollback journal, it is not put there by by this routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4993
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4994
** References to the page pPg remain valid. Updating any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4995
** meta-data associated with pPg (i.e. data stored in the nExtra bytes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4996
** allocated along with the page) is the responsibility of the caller.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4997
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4998
** A transaction must be active when this routine is called. It used to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4999
** required that a statement transaction was not active, but this restriction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5000
** has been removed (CREATE INDEX needs to move a page when a statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5001
** transaction is active).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5002
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5003
int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5004
  PgHdr *pPgOld;  /* The page being overwritten. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5005
  int h;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5006
  Pgno needSyncPgno = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5007
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5008
  pagerEnter(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5009
  assert( pPg->nRef>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5010
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5011
  PAGERTRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5012
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5013
  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5014
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5015
  pager_get_content(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5016
  if( pPg->needSync ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5017
    needSyncPgno = pPg->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5018
    assert( pPg->inJournal || (int)pgno>pPager->origDbSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5019
    assert( pPg->dirty );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5020
    assert( pPager->needSync );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5021
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5023
  /* Unlink pPg from its hash-chain */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5024
  unlinkHashChain(pPager, pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5025
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5026
  /* If the cache contains a page with page-number pgno, remove it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5027
  ** from its hash chain. Also, if the PgHdr.needSync was set for 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5028
  ** page pgno before the 'move' operation, it needs to be retained 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5029
  ** for the page moved there.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5030
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5031
  pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5032
  pPgOld = pager_lookup(pPager, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5033
  if( pPgOld ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5034
    assert( pPgOld->nRef==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5035
    unlinkHashChain(pPager, pPgOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5036
    makeClean(pPgOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5037
    pPg->needSync = pPgOld->needSync;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5038
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5039
    pPg->needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5040
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5041
  if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5042
    pPg->inJournal =  (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5043
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5044
    pPg->inJournal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5045
    assert( pPg->needSync==0 || (int)pgno>pPager->origDbSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5046
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5047
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5048
  /* Change the page number for pPg and insert it into the new hash-chain. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5049
  assert( pgno!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5050
  pPg->pgno = pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5051
  h = pgno & (pPager->nHash-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5052
  if( pPager->aHash[h] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5053
    assert( pPager->aHash[h]->pPrevHash==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5054
    pPager->aHash[h]->pPrevHash = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5055
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5056
  pPg->pNextHash = pPager->aHash[h];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5057
  pPager->aHash[h] = pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5058
  pPg->pPrevHash = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5059
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5060
  makeDirty(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5061
  pPager->dirtyCache = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5062
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5063
  if( needSyncPgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5064
    /* If needSyncPgno is non-zero, then the journal file needs to be 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5065
    ** sync()ed before any data is written to database file page needSyncPgno.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5066
    ** Currently, no such page exists in the page-cache and the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5067
    ** Pager.aInJournal bit has been set. This needs to be remedied by loading
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5068
    ** the page into the pager-cache and setting the PgHdr.needSync flag.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5069
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5070
    ** The sqlite3PagerGet() call may cause the journal to sync. So make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5071
    ** sure the Pager.needSync flag is set too.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5072
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5073
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5074
    PgHdr *pPgHdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5075
    assert( pPager->needSync );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5076
    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5077
    if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5078
    pPager->needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5079
    pPgHdr->needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5080
    pPgHdr->inJournal = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5081
    makeDirty(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5082
    sqlite3PagerUnref(pPgHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5083
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5084
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5085
  pagerLeave(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5086
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5087
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5088
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5089
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5090
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5091
** Return a pointer to the data for the specified page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5092
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5093
void *sqlite3PagerGetData(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5094
  return PGHDR_TO_DATA(pPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5095
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5096
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5097
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5098
** Return a pointer to the Pager.nExtra bytes of "extra" space 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5099
** allocated along with the specified page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5100
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5101
void *sqlite3PagerGetExtra(DbPage *pPg){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5102
  Pager *pPager = pPg->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5103
  return (pPager?PGHDR_TO_EXTRA(pPg, pPager):0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5104
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5105
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5106
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5107
** Get/set the locking-mode for this pager. Parameter eMode must be one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5108
** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5109
** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5110
** the locking-mode is set to the value specified.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5111
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5112
** The returned value is either PAGER_LOCKINGMODE_NORMAL or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5113
** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5114
** locking-mode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5115
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5116
int sqlite3PagerLockingMode(Pager *pPager, int eMode){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5117
  assert( eMode==PAGER_LOCKINGMODE_QUERY
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5118
            || eMode==PAGER_LOCKINGMODE_NORMAL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5119
            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5120
  assert( PAGER_LOCKINGMODE_QUERY<0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5121
  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5122
  if( eMode>=0 && !pPager->tempFile ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5123
    pPager->exclusiveMode = eMode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5124
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5125
  return (int)pPager->exclusiveMode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5126
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5127
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5128
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5129
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5130
** Print a listing of all referenced pages and their ref count.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5131
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5132
void sqlite3PagerRefdump(Pager *pPager){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5133
  PgHdr *pPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5134
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5135
    if( pPg->nRef<=0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5136
    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5137
       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5138
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5139
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5140
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5141
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5142
#endif /* SQLITE_OMIT_DISKIO */