engine/sqlite/src/pager.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
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 */