engine/sqlite/src/btree.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
** 2004 April 6
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
** $Id: btree.cpp 1282 2008-11-13 09:31:33Z LarsPson $
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
** This file implements a external (disk-based) database using BTrees.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** See the header comment on "btreeInt.h" for additional information.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** Including a description of file format and an overview of operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
#include "btreeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
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
** The header string that appears at the beginning of every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
** SQLite database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
static const char zMagicHeader[] = SQLITE_FILE_HEADER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
** Set this global variable to 1 to enable tracing using the TRACE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** macro.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
#if SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
int sqlite3_btree_trace=0;  /* True to enable tracing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
** A flag to indicate whether or not shared cache is enabled.  Also,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
** a list of BtShared objects that are eligible for participation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
** in shared cache.  The variables have file scope during normal builds,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
** but the test harness needs to access these variables so we make them
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
** global for test builds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
BtShared *sqlite3SharedCacheList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
int sqlite3SharedCacheEnabled = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
static BtShared *sqlite3SharedCacheList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
static int sqlite3SharedCacheEnabled = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
#endif /* SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
** Enable or disable the shared pager and schema features.
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
** This routine has no effect on existing database connections.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
** The shared cache setting effects only future calls to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
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
EXPORT_C int sqlite3_enable_shared_cache(int enable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
  sqlite3SharedCacheEnabled = enable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
** Forward declaration
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
static int checkReadLocks(Btree*,Pgno,BtCursor*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
#ifdef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  ** The functions queryTableLock(), lockTable() and unlockAllTables()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  ** manipulate entries in the BtShared.pLock linked list used to store
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
  ** shared-cache table level locks. If the library is compiled with the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  ** shared-cache feature disabled, then there is only ever one user
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  ** of each BtShared structure and so this locking is not necessary. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  ** So define the lock related functions as no-ops.
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
  #define queryTableLock(a,b,c) SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  #define lockTable(a,b,c) SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  #define unlockAllTables(a)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
#ifndef SQLITE_OMIT_SHARED_CACHE
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
** Query to see if btree handle p may obtain a lock of type eLock 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** SQLITE_LOCKED if not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  BtLock *pIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  /* This is a no-op if the shared-cache is not enabled */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
  if( !p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
    return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
  /* This (along with lockTable()) is where the ReadUncommitted flag is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  ** dealt with. If the caller is querying for a read-lock and the flag is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
  ** set, it is unconditionally granted - even if there are write-locks
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
  ** is not considered.
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
  ** In function lockTable(), if a read-lock is demanded and the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  ** ReadUncommitted flag is set, no entry is added to the locks list 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
  ** (BtShared.pLock).
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
  ** To summarize: If the ReadUncommitted flag is set, then read cursors do
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  ** not create or respect table locks. The locking procedure for a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
  ** write-cursor does not change.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
    !p->db || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
    0==(p->db->flags&SQLITE_ReadUncommitted) || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
    eLock==WRITE_LOCK ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
    iTab==MASTER_ROOT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      if( pIter->pBtree!=p && pIter->iTable==iTab && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
          (pIter->eLock!=eLock || eLock!=READ_LOCK) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
        return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
      }
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
#endif /* !SQLITE_OMIT_SHARED_CACHE */
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
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
** Add a lock on the table with root-page iTable to the shared-btree used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
** by Btree handle p. Parameter eLock must be either READ_LOCK or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
** WRITE_LOCK.
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
** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
** SQLITE_NOMEM may also be returned.
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
static int lockTable(Btree *p, Pgno iTable, u8 eLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  BtLock *pLock = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  BtLock *pIter;
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
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  /* This is a no-op if the shared-cache is not enabled */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  if( !p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    return SQLITE_OK;
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
  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
  /* If the read-uncommitted flag is set and a read-lock is requested,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  ** return early without adding an entry to the BtShared.pLock list. See
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  ** comment in function queryTableLock() for more info on handling 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
  ** the ReadUncommitted flag.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
    (p->db) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
    (p->db->flags&SQLITE_ReadUncommitted) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
    (eLock==READ_LOCK) &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
    iTable!=MASTER_ROOT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
    return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  /* First search the list for an existing lock on this table. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
    if( pIter->iTable==iTable && pIter->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
      pLock = pIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
  }
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
  /* If the above search did not find a BtLock struct associating Btree p
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
  ** with table iTable, allocate one and link it into the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  if( !pLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
    pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
    if( !pLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
      return SQLITE_NOMEM;
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
    pLock->iTable = iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    pLock->pBtree = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
    pLock->pNext = pBt->pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
    pBt->pLock = pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
  /* Set the BtLock.eLock variable to the maximum of the current lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  ** and the requested lock. This means if a write-lock was already held
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
  ** and a read-lock requested, we don't incorrectly downgrade the lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
  assert( WRITE_LOCK>READ_LOCK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  if( eLock>pLock->eLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
    pLock->eLock = eLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
  return SQLITE_OK;
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
#endif /* !SQLITE_OMIT_SHARED_CACHE */
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
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
** Release all the table locks (locks obtained via calls to the lockTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
** procedure) held by Btree handle p.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
static void unlockAllTables(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
  BtLock **ppIter = &p->pBt->pLock;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
  assert( p->sharable || 0==*ppIter );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
  while( *ppIter ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
    BtLock *pLock = *ppIter;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
    if( pLock->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
      *ppIter = pLock->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
      sqlite3_free(pLock);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
      ppIter = &pLock->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
#endif /* SQLITE_OMIT_SHARED_CACHE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
static void releasePage(MemPage *pPage);  /* Forward reference */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
** Verify that the cursor holds a mutex on the BtShared
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
static int cursorHoldsMutex(BtCursor *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  return sqlite3_mutex_held(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
** Invalidate the overflow page-list cache for cursor pCur, if any.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
static void invalidateOverflowCache(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  sqlite3_free(pCur->aOverflow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  pCur->aOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Invalidate the overflow page-list cache for all cursors opened
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
** on the shared btree structure pBt.
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
static void invalidateAllOverflowCache(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
    invalidateOverflowCache(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
  #define invalidateOverflowCache(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
  #define invalidateAllOverflowCache(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
** Save the current cursor position in the variables BtCursor.nKey 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
static int saveCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  assert( CURSOR_VALID==pCur->eState );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  assert( 0==pCur->pKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  assert( cursorHoldsMutex(pCur) );
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
  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  /* If this is an intKey table, then the above call to BtreeKeySize()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  ** stores the integer key in pCur->nKey. In this case this value is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  ** all that is required. Otherwise, if pCur is not open on an intKey
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  ** table, then malloc space for and store the pCur->nKey bytes of key 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
  ** data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
    void *pKey = sqlite3_malloc(pCur->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
    if( pKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
      rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
        pCur->pKey = pKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
        sqlite3_free(pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
      rc = SQLITE_NOMEM;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
  assert( !pCur->pPage->intKey || !pCur->pKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
    pCur->pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    pCur->eState = CURSOR_REQUIRESEEK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  invalidateOverflowCache(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
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
** Save the positions of all cursors except pExcept open on the table 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
** with root-page iRoot. Usually, this is called just before cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  assert( pExcept==0 || pExcept->pBt==pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
        p->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
      int rc = saveCursorPosition(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
      if( SQLITE_OK!=rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
      }
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
** Clear the current cursor position.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
static void clearCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
  sqlite3_free(pCur->pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  pCur->pKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
** Restore the cursor to the position it was in (or as close to as possible)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
** when saveCursorPosition() was called. Note that this call deletes the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
** saved position info stored by saveCursorPosition(), so there can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
** at most one effective restoreOrClearCursorPosition() call after each 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
** saveCursorPosition().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
** If the second argument argument - doSeek - is false, then instead of 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
** returning the cursor to its saved position, any saved position is deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
** and the cursor state set to CURSOR_INVALID.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
  assert( pCur->eState>=CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  if( pCur->isIncrblobHandle ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
    return SQLITE_ABORT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
    sqlite3_free(pCur->pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
    pCur->pKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
#define restoreOrClearCursorPosition(p) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
  (p->eState>=CURSOR_REQUIRESEEK ? \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
         sqlite3BtreeRestoreOrClearCursorPosition(p) : \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
         SQLITE_OK)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
** Given a page number of a regular database page, return the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
** number for the pointer-map page that contains the entry for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
** input page number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  int nPagesPerMapPage, iPtrMap, ret;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  nPagesPerMapPage = (pBt->usableSize/5)+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  iPtrMap = (pgno-2)/nPagesPerMapPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  ret = (iPtrMap*nPagesPerMapPage) + 2; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  if( ret==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
    ret++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
  return ret;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
** Write an entry into the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
** This routine updates the pointer map entry for page number 'key'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
** so that it maps to type 'eType' and parent page number 'pgno'.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
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
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
  DbPage *pDbPage;  /* The pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
  u8 *pPtrmap;      /* The pointer map data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
  Pgno iPtrmap;     /* The pointer map page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
  int offset;       /* Offset in pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
  /* The master-journal page number must never be used as a pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
  assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
  assert( pBt->autoVacuum );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
  if( key==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
  iPtrmap = PTRMAP_PAGENO(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
  offset = PTRMAP_PTROFFSET(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
  if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
    TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
    rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
      pPtrmap[offset] = eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
      put4byte(&pPtrmap[offset+1], parent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
  }
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
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
** Read an entry from the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
** This routine retrieves the pointer map entry for page 'key', writing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** the type and parent page number to *pEType and *pPgno respectively.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
  DbPage *pDbPage;   /* The pointer map page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
  int iPtrmap;       /* Pointer map page index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
  u8 *pPtrmap;       /* Pointer map page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
  int offset;        /* Offset of entry in pointer map */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  iPtrmap = PTRMAP_PAGENO(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
  if( rc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
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
  offset = PTRMAP_PTROFFSET(pBt, key);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  assert( pEType!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  *pEType = pPtrmap[offset];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
  return SQLITE_OK;
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
#endif /* SQLITE_OMIT_AUTOVACUUM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
** Given a btree page and a cell index (0 means the first cell on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
** the page, 1 means the second cell, and so forth) return a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
** to the cell content.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
** This routine works only for pages that do not contain overflow cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
#define findCell(pPage, iCell) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
  ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)]))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  assert( iCell>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
  assert( iCell<get2byte(&pPage->aData[pPage->hdrOffset+3]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
  return findCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
** This a more complex version of sqlite3BtreeFindCell() that works for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
** pages that do contain overflow cells.  See insert
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
static u8 *findOverflowCell(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
  for(i=pPage->nOverflow-1; i>=0; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
    int k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
	MemPage::_OvflCell *pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
    pOvfl = &pPage->aOvfl[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
    k = pOvfl->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
    if( k<=iCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
      if( k==iCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
        return pOvfl->pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
      iCell--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
  return findCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
** Parse a cell content block and fill in the CellInfo structure.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
** are two versions of this function.  sqlite3BtreeParseCell() takes a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
** cell index as the second argument and sqlite3BtreeParseCellPtr() 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
** takes a pointer to the body of the cell as its second argument.
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
** Within this file, the parseCell() macro can be called instead of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
void sqlite3BtreeParseCellPtr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  MemPage *pPage,         /* Page containing the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
  u8 *pCell,              /* Pointer to the cell text. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
  CellInfo *pInfo         /* Fill in this structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
  int n;                  /* Number bytes in cell content header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  u32 nPayload;           /* Number of bytes of cell payload */
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
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
  pInfo->pCell = pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
  assert( pPage->leaf==0 || pPage->leaf==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  n = pPage->childPtrSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  assert( n==4-4*pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
  if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
    n += getVarint32(&pCell[n], &nPayload);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
    nPayload = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
  pInfo->nData = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
    u32 x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
    n += getVarint32(&pCell[n], &x);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
    pInfo->nKey = x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
    nPayload += x;
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
  pInfo->nPayload = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
  pInfo->nHeader = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
  if( nPayload<=pPage->maxLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
    /* This is the (easy) common case where the entire payload fits
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
    ** on the local page.  No overflow is required.
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
    int nSize;          /* Total size of cell content in bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
    pInfo->nLocal = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
    pInfo->iOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
    nSize = nPayload + n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
    if( nSize<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
      nSize = 4;        /* Minimum cell size is 4 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
    pInfo->nSize = nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
    /* If the payload will not fit completely on the local page, we have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
    ** to decide how much to store locally and how much to spill onto
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
    ** overflow pages.  The strategy is to minimize the amount of unused
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
    ** space on overflow pages while keeping the amount of local storage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
    ** in between minLocal and maxLocal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    ** Warning:  changing the way overflow payload is distributed in any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
    ** way will result in an incompatible file format.
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
    int minLocal;  /* Minimum amount of payload held locally */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
    int maxLocal;  /* Maximum amount of payload held locally */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
    int surplus;   /* Overflow payload available for local storage */
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
    minLocal = pPage->minLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
    maxLocal = pPage->maxLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
    if( surplus <= maxLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
      pInfo->nLocal = surplus;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
      pInfo->nLocal = minLocal;
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
    pInfo->iOverflow = pInfo->nLocal + n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
    pInfo->nSize = pInfo->iOverflow + 4;
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
#define parseCell(pPage, iCell, pInfo) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
void sqlite3BtreeParseCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  MemPage *pPage,         /* Page containing the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  int iCell,              /* The cell index.  First cell is 0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  CellInfo *pInfo         /* Fill in this structure */
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
  parseCell(pPage, iCell, pInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
** Compute the total number of bytes that a Cell needs in the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
** data area of the btree-page.  The return number includes the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
** data header and the local payload, but not any overflow page or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
** the space used by the cell pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
static int cellSize(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  sqlite3BtreeParseCell(pPage, iCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
  return info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
static int cellSizePtr(MemPage *pPage, u8 *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
  return info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
}
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
#ifndef SQLITE_OMIT_AUTOVACUUM
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
** If the cell pCell, part of page pPage contains a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
** to an overflow page, insert an entry into the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
** for the overflow page.
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 int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
  if( pCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
    assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
    if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
      Pgno ovfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
      return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
    }
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
  return SQLITE_OK;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
** If the cell with index iCell on page pPage contains a pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
** to an overflow page, insert an entry into the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
** for the overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
static int ptrmapPutOvfl(MemPage *pPage, int iCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
  u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
  pCell = findOverflowCell(pPage, iCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
  return ptrmapPutOvflPtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
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
** Defragment the page given.  All Cells are moved to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
** end of the page and all free space is collected into one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
** big FreeBlk that occurs in between the header and cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
** pointer array and the cell content area.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
static int defragmentPage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
  int i;                     /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
  int pc;                    /* Address of a i-th cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
  int addr;                  /* Offset of first byte after cell pointer array */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
  int hdr;                   /* Offset to the page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
  int size;                  /* Size of a cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
  int usableSize;            /* Number of usable bytes on a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
  int cellOffset;            /* Offset to the cell pointer array */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
  int brk;                   /* Offset to the cell content area */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
  int nCell;                 /* Number of cells on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
  unsigned char *data;       /* The page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
  unsigned char *temp;       /* Temp area for cell content */
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
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
  assert( pPage->pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
  assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
  temp = (unsigned char*)sqlite3PagerTempSpace(pPage->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
  cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
  nCell = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
  assert( nCell==get2byte(&data[hdr+3]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
  usableSize = pPage->pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
  brk = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
  memcpy(&temp[brk], &data[brk], usableSize - brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
  brk = usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
    u8 *pAddr;     /* The i-th cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
    pAddr = &data[cellOffset + i*2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
    pc = get2byte(pAddr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
    assert( pc<pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
    size = cellSizePtr(pPage, &temp[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
    brk -= size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
    memcpy(&data[brk], &temp[pc], size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
    put2byte(pAddr, brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
  assert( brk>=cellOffset+2*nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
  put2byte(&data[hdr+5], brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
  data[hdr+1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
  data[hdr+2] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
  data[hdr+7] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
  addr = cellOffset+2*nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
  memset(&data[addr], 0, brk-addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
  return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
** Allocate nByte bytes of space on a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
** Return the index into pPage->aData[] of the first byte of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
** the new allocation. Or return 0 if there is not enough free
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
** space on the page to satisfy the allocation request.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
** If the page contains nBytes of free space but does not contain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
** nBytes of contiguous free space, then this routine automatically
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
** calls defragementPage() to consolidate all free space before 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
** allocating the new chunk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
static int allocateSpace(MemPage *pPage, int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
  int addr, pc, hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
  int size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  int nFrag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
  int top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
  int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
  int cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
  unsigned char *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
  assert( pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
  if( nByte<4 ) nByte = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
  if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
  pPage->nFree -= nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  nFrag = data[hdr+7];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
  if( nFrag<60 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
    /* Search the freelist looking for a slot big enough to satisfy the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
    ** space request. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
    addr = hdr+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
    while( (pc = get2byte(&data[addr]))>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
      size = get2byte(&data[pc+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
      if( size>=nByte ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
        if( size<nByte+4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
          memcpy(&data[addr], &data[pc], 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
          data[hdr+7] = nFrag + size - nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
          return pc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
          put2byte(&data[pc+2], size-nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
          return pc + size - nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
      addr = pc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
  /* Allocate memory from the gap in between the cell pointer array
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
  ** and the cell content area.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
  top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
  nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
  cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
  if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
    if( defragmentPage(pPage) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
  top -= nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
  assert( cellOffset + 2*nCell <= top );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
  put2byte(&data[hdr+5], top);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
  return top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
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
** Return a section of the pPage->aData to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
** The first byte of the new free block is pPage->aDisk[start]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
** and the size of the block is "size" bytes.
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
** Most of the effort here is involved in coalesing adjacent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
** free blocks into a single big free block.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
static void freeSpace(MemPage *pPage, int start, int size){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  int addr, pbegin, hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
  unsigned char *data = pPage->aData;
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
  assert( pPage->pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
  assert( (start + size)<=pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
  if( size<4 ) size = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
#ifdef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
  /* Overwrite deleted information with zeros when the SECURE_DELETE 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
  ** option is enabled at compile-time */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
  memset(&data[start], 0, size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
  /* Add the space back into the linked list of freeblocks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  addr = hdr + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
    assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
    assert( pbegin>addr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
    addr = pbegin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
  assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  assert( pbegin>addr || pbegin==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
  put2byte(&data[addr], start);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
  put2byte(&data[start], pbegin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
  put2byte(&data[start+2], size);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
  pPage->nFree += size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
  /* Coalesce adjacent free blocks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
  addr = pPage->hdrOffset + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
  while( (pbegin = get2byte(&data[addr]))>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
    int pnext, psize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
    assert( pbegin>addr );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
    assert( pbegin<=pPage->pBt->usableSize-4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
    pnext = get2byte(&data[pbegin]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
    psize = get2byte(&data[pbegin+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
    if( pbegin + psize + 3 >= pnext && pnext>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
      int frag = pnext - (pbegin+psize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
      assert( frag<=data[pPage->hdrOffset+7] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
      data[pPage->hdrOffset+7] -= frag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
      put2byte(&data[pbegin], get2byte(&data[pnext]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
      put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
      addr = pbegin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
  /* If the cell content area begins with a freeblock, remove it. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
  if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
    int top;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
    pbegin = get2byte(&data[hdr+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
    memcpy(&data[hdr+1], &data[pbegin], 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
    put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2]));
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
}
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
** Decode the flags byte (the first byte of the header) for a page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
** and initialize fields of the MemPage structure accordingly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
static void decodeFlags(MemPage *pPage, int flagByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
  BtShared *pBt;     /* A copy of pPage->pBt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
  pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
  pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  pPage->leaf = (flagByte & PTF_LEAF)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  pPage->childPtrSize = 4*(pPage->leaf==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  if( flagByte & PTF_LEAFDATA ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
    pPage->leafData = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
    pPage->maxLocal = pBt->maxLeaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
    pPage->minLocal = pBt->minLeaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
    pPage->leafData = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
    pPage->maxLocal = pBt->maxLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
    pPage->minLocal = pBt->minLocal;
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
  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
** Initialize the auxiliary information for a disk block.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
** The pParent parameter must be a pointer to the MemPage which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
** is the parent of the page being initialized.  The root of a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
** BTree has no parent and so for that page, pParent==NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
** Return SQLITE_OK on success.  If we see that the page does
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
** not contain a well-formed database page, then return 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
** guarantee that the page is well-formed.  It only shows that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
** we failed to detect any corruption.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
int sqlite3BtreeInitPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
  MemPage *pPage,        /* The page to be initialized */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
  MemPage *pParent       /* The parent.  Might be NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
  int pc;            /* Address of a freeblock within pPage->aData[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
  int hdr;           /* Offset to beginning of page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
  u8 *data;          /* Equal to pPage->aData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
  BtShared *pBt;        /* The main btree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
  int usableSize;    /* Amount of usable space on each page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
  int cellOffset;    /* Offset from start of page to first cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
  int nFree;         /* Number of unused bytes on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
  int top;           /* First byte of the cell content area */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
  assert( pBt!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
  assert( pParent==0 || pParent->pBt==pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
  assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
  assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
  if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
    /* The parent page should never change unless the file is corrupt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
  if( pPage->isInit ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
  if( pPage->pParent==0 && pParent!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
    pPage->pParent = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
    sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
  decodeFlags(pPage, data[hdr]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
  pPage->nOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
  pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
  top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
  pPage->nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
  if( pPage->nCell>MX_CELL(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
    /* To many cells for a single page.  The page must be corrupt */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
  if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
    /* All pages must have at least one cell, except for root pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
  }
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
  /* Compute the total free space on the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
  pc = get2byte(&data[hdr+1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
  nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
  while( pc>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
    int next, size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
    if( pc>usableSize-4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
      /* Free block is off the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
      return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
    next = get2byte(&data[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
    size = get2byte(&data[pc+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
    if( next>0 && next<=pc+size+3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
      /* Free blocks must be in accending order */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
      return SQLITE_CORRUPT_BKPT; 
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
    nFree += size;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
    pc = next;
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
  pPage->nFree = nFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
  if( nFree>=usableSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
    /* Free space cannot exceed total page size */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
    return SQLITE_CORRUPT_BKPT; 
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
  pPage->isInit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
  return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
** Set up a raw page so that it looks like a database page holding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
** no entries.
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
static void zeroPage(MemPage *pPage, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
  unsigned char *data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
  int hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
  int first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
  assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  assert( sqlite3PagerGetData(pPage->pDbPage) == data );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
  memset(&data[hdr], 0, pBt->usableSize - hdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
  data[hdr] = flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
  memset(&data[hdr+1], 0, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
  data[hdr+7] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
  put2byte(&data[hdr+5], pBt->usableSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
  pPage->nFree = pBt->usableSize - first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
  decodeFlags(pPage, flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
  pPage->hdrOffset = hdr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
  pPage->cellOffset = first;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
  pPage->nOverflow = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
  pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
  pPage->nCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
  pPage->isInit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
** Get a page from the pager.  Initialize the MemPage.pBt and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
** MemPage.aData elements if needed.
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 the noContent flag is set, it means that we do not care about
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
** the content of the page at this time.  So do not go to the disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
** to fetch the content.  Just fill in the content with zeros for now.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
** If in the future we call sqlite3PagerWrite() on this page, that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
** means we have started to be concerned about content and the disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
** read should occur at that point.
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
int sqlite3BtreeGetPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
  BtShared *pBt,       /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
  Pgno pgno,           /* Number of the page to fetch */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
  MemPage **ppPage,    /* Return the page in this parameter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  int noContent        /* Do not load page content if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  pPage->aData = (u8*)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
  pPage->pDbPage = pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
  pPage->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  pPage->pgno = pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
  *ppPage = pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
  return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
** Get a page from the pager and initialize it.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
** is just a convenience wrapper around separate calls to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
** sqlite3BtreeGetPage() and sqlite3BtreeInitPage().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
static int getAndInitPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
  BtShared *pBt,          /* The database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
  Pgno pgno,           /* Number of the page to get */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
  MemPage **ppPage,    /* Write the page pointer here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
  MemPage *pParent     /* Parent of the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  if( pgno==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
    return SQLITE_CORRUPT_BKPT; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
    rc = sqlite3BtreeInitPage(*ppPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
** Release a MemPage.  This should be called once for each prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
** call to sqlite3BtreeGetPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
static void releasePage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
  if( pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
    assert( pPage->aData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
    assert( pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
    assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
    sqlite3PagerUnref(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
** This routine is called when the reference count for a page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
** reaches zero.  We need to unref the pParent pointer when that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
** happens.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
static void pageDestructor(DbPage *pData, int pageSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
  assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
  assert( pPage->isInit==0 || sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
  if( pPage->pParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
    MemPage *pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
    assert( pParent->pBt==pPage->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
    pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
    releasePage(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
  pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
** During a rollback, when the pager reloads information into the cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
** so that the cache is restored to its original state at the start of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
** the transaction, for each page restored this routine is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
** This routine needs to reset the extra data section at the end of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
** page to agree with the restored data.
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
static void pageReinit(DbPage *pData, int pageSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
  assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  pPage = (MemPage *)sqlite3PagerGetExtra(pData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  if( pPage->isInit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
    pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
    sqlite3BtreeInitPage(pPage, pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
** Invoke the busy handler for a btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
static int sqlite3BtreeInvokeBusyHandler(void *pArg, int n){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  BtShared *pBt = (BtShared*)pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
  assert( pBt->db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
  assert( sqlite3_mutex_held(pBt->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
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
** Open a database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
** zFilename is the name of the database file.  If zFilename is NULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
** a new database with a random name is created.  This randomly named
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
** database file will be deleted when sqlite3BtreeClose() is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
** If zFilename is ":memory:" then an in-memory database is created
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
** that is automatically destroyed when it is closed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
int sqlite3BtreeOpen(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
  const char *zFilename,  /* Name of the file containing the BTree database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
  sqlite3 *db,            /* Associated database handle */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
  Btree **ppBtree,        /* Pointer to new Btree object written here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
  int flags,              /* Options */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
  int vfsFlags            /* Flags passed through to sqlite3_vfs.xOpen() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
  sqlite3_vfs *pVfs;      /* The VFS to use for this btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
  BtShared *pBt = 0;      /* Shared part of btree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
  Btree *p;               /* Handle to return */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
  int nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
  unsigned char zDbHeader[100];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
  /* Set the variable isMemdb to true for an in-memory database, or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
  ** false for a file-based database. This symbol is only required if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
  ** either of the shared-data or autovacuum features are compiled 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
  ** into the library.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  #ifdef SQLITE_OMIT_MEMORYDB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
    const int isMemdb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
  #else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
    const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
  #endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
#endif
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
  assert( db!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
  assert( sqlite3_mutex_held(db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
  pVfs = db->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
  p = (Btree*)sqlite3MallocZero(sizeof(Btree));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
  if( !p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
    return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
  p->db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
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
  ** If this Btree is a candidate for shared cache, try to find an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
  ** existing BtShared object that we can share with
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
  if( (flags & BTREE_PRIVATE)==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
   && isMemdb==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
   && (db->flags & SQLITE_Vtab)==0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
   && zFilename && zFilename[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
    if( sqlite3SharedCacheEnabled ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
      int nFullPathname = pVfs->mxPathname+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
      char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
      sqlite3_mutex *mutexShared;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
      p->sharable = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
      if( db ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
        db->flags |= SQLITE_SharedCache;
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
      if( !zFullPathname ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
        sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
        return SQLITE_NOMEM;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
      sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
      sqlite3_mutex_enter(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
      for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
        assert( pBt->nRef>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
        if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
                 && sqlite3PagerVfs(pBt->pPager)==pVfs ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
          p->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
          pBt->nRef++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
      sqlite3_mutex_leave(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
      sqlite3_free(zFullPathname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
    else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
      /* In debug mode, we mark all persistent databases as sharable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
      ** even when they are not.  This exercises the locking code and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
      ** gives more opportunity for asserts(sqlite3_mutex_held())
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
      ** statements to find locking problems.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
      p->sharable = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  if( pBt==0 ){
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
	/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
    ** The following asserts make sure that structures used by the btree are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
    ** the right size.  This is to guard against size changes that result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
    ** when compiling on a different architecture.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
    assert( sizeof(i64)==8 || sizeof(i64)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
    assert( sizeof(u64)==8 || sizeof(u64)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
    assert( sizeof(u32)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
    assert( sizeof(u16)==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
    assert( sizeof(Pgno)==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
    pBt = (BtShared*)sqlite3MallocZero( sizeof(*pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
    if( pBt==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
      goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
    pBt->busyHdr.xFunc = sqlite3BtreeInvokeBusyHandler;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
    pBt->busyHdr.pArg = pBt;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
	rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
                          EXTRA_SIZE, flags, vfsFlags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
      rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
      goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    sqlite3PagerSetBusyhandler(pBt->pPager, &pBt->busyHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
    p->pBt = pBt;
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
    sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
    sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
    pBt->pCursor = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
    pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
    pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
    pBt->pageSize = get2byte(&zDbHeader[16]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
    if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
         || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
      pBt->pageSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
      sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
      pBt->maxEmbedFrac = 64;   /* 25% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
      pBt->minEmbedFrac = 32;   /* 12.5% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
      pBt->minLeafFrac = 32;    /* 12.5% */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
      /* If the magic name ":memory:" will create an in-memory database, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
      ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
      ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
      ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
      ** regular file-name. In this case the auto-vacuum applies as per normal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
      if( zFilename && !isMemdb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
        pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
        pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
      nReserve = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
      nReserve = zDbHeader[20];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
      pBt->maxEmbedFrac = zDbHeader[21];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
      pBt->minEmbedFrac = zDbHeader[22];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
      pBt->minLeafFrac = zDbHeader[23];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
      pBt->pageSizeFixed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
      pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
      pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
    pBt->usableSize = pBt->pageSize - nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
    assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
    sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
    /* Add the new BtShared object to the linked list sharable BtShareds.
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
    if( p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
      sqlite3_mutex *mutexShared;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
      pBt->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
      if( SQLITE_THREADSAFE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
        pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
        if( pBt->mutex==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
          rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
          db->mallocFailed = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
          goto btree_open_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
      sqlite3_mutex_enter(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
      pBt->pNext = sqlite3SharedCacheList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
      sqlite3SharedCacheList = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
      sqlite3_mutex_leave(mutexShared);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
  /* If the new Btree uses a sharable pBtShared, then link the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
  ** Btree into the list of all sharable Btrees for the same connection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
  ** The list is kept in ascending order by pBt address.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
  if( p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
    Btree *pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
    for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
      if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
        while( pSib->pPrev ){ pSib = pSib->pPrev; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
        if( p->pBt<pSib->pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
          p->pNext = pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
          p->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
          pSib->pPrev = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
          while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
            pSib = pSib->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
          p->pNext = pSib->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
          p->pPrev = pSib;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
          if( p->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
            p->pNext->pPrev = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
          pSib->pNext = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
        break;
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
  *ppBtree = p;
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
btree_open_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
    if( pBt && pBt->pPager ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
      sqlite3PagerClose(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
    sqlite3_free(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
    sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
    *ppBtree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
  return rc;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
** Decrement the BtShared.nRef counter.  When it reaches zero,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
** remove the BtShared structure from the sharing list.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
** true if the BtShared.nRef counter reaches zero and return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
** false if it is still positive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
static int removeFromSharingList(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
  sqlite3_mutex *pMaster;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
  BtShared *pList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
  int removed = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
  assert( sqlite3_mutex_notheld(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
  pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
  sqlite3_mutex_enter(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
  pBt->nRef--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
  if( pBt->nRef<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
    if( sqlite3SharedCacheList==pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
      sqlite3SharedCacheList = pBt->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
      pList = sqlite3SharedCacheList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
      while( pList && pList->pNext!=pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
        pList=pList->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
      if( pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
        pList->pNext = pBt->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
    if( SQLITE_THREADSAFE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
      sqlite3_mutex_free(pBt->mutex);
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
    removed = 1;
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
  sqlite3_mutex_leave(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
  return removed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
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
** Close an open database and invalidate all cursors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
int sqlite3BtreeClose(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
  /* Close all cursors opened via this handle.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
  pCur = pBt->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
  while( pCur ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
    BtCursor *pTmp = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
    pCur = pCur->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
    if( pTmp->pBtree==p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
      sqlite3BtreeCloseCursor(pTmp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
  /* Rollback any active transaction and free the handle structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
  ** The call to sqlite3BtreeRollback() drops any table-locks held by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
  ** this handle.
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
  sqlite3BtreeRollback(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
  sqlite3BtreeLeave(p);
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
  /* If there are still other outstanding references to the shared-btree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
  ** structure, return now. The remainder of this procedure cleans 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
  ** up the shared-btree.
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
  assert( p->wantToLock==0 && p->locked==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
  if( !p->sharable || removeFromSharingList(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
    /* The pBt is no longer on the sharing list, so we can access
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
    ** it without having to hold the mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
    ** Clean out and delete the BtShared object.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
    assert( !pBt->pCursor );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
    sqlite3PagerClose(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
    if( pBt->xFreeSchema && pBt->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
      pBt->xFreeSchema(pBt->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
    sqlite3_free(pBt->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
    sqlite3_free(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
  }
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
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
  assert( p->wantToLock==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
  assert( p->locked==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
  if( p->pPrev ) p->pPrev->pNext = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
  if( p->pNext ) p->pNext->pPrev = p->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
  sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
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
** Change the limit on the number of pages allowed in the cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
** The maximum number of cache pages is set to the absolute
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
** value of mxPage.  If mxPage is negative, the pager will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
** operate asynchronously - it will not stop to do fsync()s
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
** to insure data is written to the disk surface before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
** continuing.  Transactions still work if synchronous is off,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
** and the database cannot be corrupted if this program
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
** crashes.  But if the operating system crashes or there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
** an abrupt power failure when synchronous is off, the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
** could be left in an inconsistent and unrecoverable state.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
** Synchronous is on by default so database corruption is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
** normally a worry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
  sqlite3PagerSetCachesize(pBt->pPager, mxPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
  return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
** Change the way data is synced to disk in order to increase or decrease
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
** how well the database resists damage due to OS crashes and power
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
** there is a high probability of damage)  Level 2 is the default.  There
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
** is a very low but non-zero probability of damage.  Level 3 reduces the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
** probability of damage to near zero but with a write performance reduction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
  sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
** Return TRUE if the given btree is set to safety level 1.  In other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
** words, return TRUE if no sync() occurs on the disk files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
int sqlite3BtreeSyncDisabled(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
  assert( sqlite3_mutex_held(p->db->mutex) );  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
  assert( pBt && pBt->pPager );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
  rc = sqlite3PagerNosync(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
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
** Change the default pages size and the number of reserved bytes per page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
** The page size must be a power of 2 between 512 and 65536.  If the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
** size supplied does not meet this constraint then the page size is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
** changed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
** Page sizes are constrained to be a power of two so that the region
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
** of the database file used for locking (beginning at PENDING_BYTE,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
** the first byte past the 1GB boundary, 0x40000000) needs to occur
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
** at the beginning of a page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
** If parameter nReserve is less than zero, then the number of reserved
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
** bytes per page is left unchanged.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
  if( pBt->pageSizeFixed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
    return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  if( nReserve<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
    nReserve = pBt->pageSize - pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
        ((pageSize-1)&pageSize)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
    assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
    assert( !pBt->pPage1 && !pBt->pCursor );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
    pBt->pageSize = pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
    rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
  pBt->usableSize = pBt->pageSize - nReserve;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
** Return the currently defined page size
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
int sqlite3BtreeGetPageSize(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
  return p->pBt->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
int sqlite3BtreeGetReserve(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
  n = p->pBt->pageSize - p->pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
** Set the maximum page count for a database if mxPage is positive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
** No changes are made if mxPage is 0 or negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
** Regardless of the value of mxPage, return the maximum page count.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  return n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
** is disabled. The default value for the auto-vacuum property is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
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
int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
  return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
  int av = (autoVacuum?1:0);
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
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
  if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1593
    rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1594
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
    pBt->autoVacuum = av;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
** enabled 1 is returned. Otherwise 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1605
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1606
int sqlite3BtreeGetAutoVacuum(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
  return BTREE_AUTOVACUUM_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
  rc = (
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
    (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
    (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
    BTREE_AUTOVACUUM_INCR
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
** Get a reference to pPage1 of the database file.  This will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
** also acquire a readlock on that file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
** SQLITE_OK is returned on success.  If the file is not a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
** well-formed database file, then SQLITE_CORRUPT is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
** is returned if we run out of memory. 
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
static int lockBtree(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
  int rc, pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
  MemPage *pPage1;
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
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
  if( pBt->pPage1 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1638
  rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1639
  if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
  
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
  /* Do some checking to help insure the file we opened really is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
  ** a valid database file. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
  rc = SQLITE_NOTADB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
  if( sqlite3PagerPagecount(pBt->pPager)>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
    u8 *page1 = pPage1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1648
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1649
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1651
    if( page1[18]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1652
      pBt->readOnly = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
    if( page1[19]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
    pageSize = get2byte(&page1[16]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
    if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
        (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1660
    ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1661
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1662
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1663
    assert( (pageSize & 7)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
    pBt->pageSize = pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1665
    pBt->usableSize = pageSize - page1[20];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1666
    if( pBt->usableSize<500 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
      goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
    pBt->maxEmbedFrac = page1[21];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
    pBt->minEmbedFrac = page1[22];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
    pBt->minLeafFrac = page1[23];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1673
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1674
    pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
  }
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
  /* maxLocal is the maximum amount of payload to store locally for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
  ** a cell.  Make sure it is small enough so that at least minFanout
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
  ** cells can will fit on one page.  We assume a 10-byte page header.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
  ** Besides the payload, the cell must store:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
  **     2-byte pointer to the cell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1683
  **     4-byte child pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1684
  **     9-byte nKey value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
  **     4-byte nData value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
  **     4-byte overflow page pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
  ** So a cell consists of a 2-byte poiner, a header which is as much as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
  ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
  ** page pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
  pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
  pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
  pBt->maxLeaf = pBt->usableSize - 35;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
  pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
  if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
    goto page1_init_failed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
  assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
  pBt->pPage1 = pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
page1_init_failed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
  releasePage(pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
  pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
** This routine works like lockBtree() except that it also invokes the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
** busy callback if there is lock contention.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
static int lockBtreeWithRetry(Btree *pRef){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
  assert( sqlite3BtreeHoldsMutex(pRef) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
  if( pRef->inTrans==TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
    u8 inTransaction = pRef->pBt->inTransaction;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
    btreeIntegrity(pRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
    rc = sqlite3BtreeBeginTrans(pRef, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
    pRef->pBt->inTransaction = inTransaction;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
    pRef->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
      pRef->pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
    btreeIntegrity(pRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
       
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1731
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1732
** If there are no outstanding cursors and we are not in the middle
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
** of a transaction but there is a read lock on the database, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
** this routine unrefs the first page of the database file which 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
** has the effect of releasing the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
** If there are any outstanding cursors, this routine is a no-op.
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 there is a transaction in progress, this routine is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
static void unlockBtreeIfUnused(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
    if( sqlite3PagerRefcount(pBt->pPager)>=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1745
      if( pBt->pPage1->aData==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1746
        MemPage *pPage = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
        pPage->aData = (u8*)sqlite3PagerGetData(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
        pPage->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
        pPage->pgno = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
      releasePage(pBt->pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
    pBt->pPage1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
    pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1758
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
** Create a new database by initializing the first page of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
** file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
static int newDatabase(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
  MemPage *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
  unsigned char *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
  if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
  pP1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
  assert( pP1!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
  data = pP1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
  rc = sqlite3PagerWrite(pP1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
  memcpy(data, zMagicHeader, sizeof(zMagicHeader));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1775
  assert( sizeof(zMagicHeader)==16 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1776
  put2byte(&data[16], pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
  data[18] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
  data[19] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
  data[20] = pBt->pageSize - pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
  data[21] = pBt->maxEmbedFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
  data[22] = pBt->minEmbedFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1782
  data[23] = pBt->minLeafFrac;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1783
  memset(&data[24], 0, 100-24);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
  zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
  pBt->pageSizeFixed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
  assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
  assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
  put4byte(&data[36 + 4*4], pBt->autoVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
  put4byte(&data[36 + 7*4], pBt->incrVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
** Attempt to start a new transaction. A write-transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
** is started if the second argument is nonzero, otherwise a read-
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
** transaction.  If the second argument is 2 or more and exclusive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
** transaction is started, meaning that no other process is allowed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
** to access the database.  A preexisting transaction may not be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
** upgraded to exclusive by calling this routine a second time - the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
** exclusivity flag only works for a new transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
** A write-transaction must be started before attempting any 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
** changes to the database.  None of the following routines 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
** will work unless a transaction is started first:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
**      sqlite3BtreeCreateTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
**      sqlite3BtreeCreateIndex()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
**      sqlite3BtreeClearTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
**      sqlite3BtreeDropTable()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
**      sqlite3BtreeInsert()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1813
**      sqlite3BtreeDelete()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1814
**      sqlite3BtreeUpdateMeta()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
** If an initial attempt to acquire the lock fails because of lock contention
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
** and the database was previously unlocked, then invoke the busy handler
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
** if there is one.  But if there was previously a read-lock, do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
** invoke the busy handler - just return SQLITE_BUSY.  SQLITE_BUSY is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1820
** returned when there is already a read-lock in order to avoid a deadlock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1821
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
** Suppose there are two processes A and B.  A has a read lock and B has
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
** a reserved lock.  B tries to promote to exclusive but is blocked because
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
** of A's read lock.  A tries to promote to reserved but is blocked by B.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
** One or the other of the two processes must give way or there can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
** no progress.  By returning SQLITE_BUSY and not invoking the busy callback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
** when A already has a read lock, we encourage A to give up and let B
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1828
** proceed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1829
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
  int rc = SQLITE_OK;
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
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1835
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1836
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
  /* If the btree is already in a write-transaction, or it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
  ** is already in a read-transaction and a read-transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
  ** is requested, this is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
  if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
    goto trans_begun;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1844
  }
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
  /* Write transactions are not possible on a read-only database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
  if( pBt->readOnly && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
    rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
    goto trans_begun;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
  }
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
  /* If another database handle has already opened a write transaction 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
  ** on this shared-btree structure and a second write transaction is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
  ** requested, return SQLITE_BUSY.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
  if( pBt->inTransaction==TRANS_WRITE && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
    rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1858
    goto trans_begun;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
  do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
    if( pBt->pPage1==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
      rc = lockBtree(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
    }
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
    if( rc==SQLITE_OK && wrflag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
      if( pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
        rc = SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
        rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
        if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
          rc = newDatabase(pBt);
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
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
      if( wrflag ) pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
      unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
  }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
          sqlite3BtreeInvokeBusyHandler(pBt, 0) );
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
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
    if( p->inTrans==TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
      pBt->nTransaction++;
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
    p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
    if( p->inTrans>pBt->inTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
      pBt->inTransaction = p->inTrans;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
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
trans_begun:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
#ifndef SQLITE_OMIT_AUTOVACUUM
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
** Set the pointer-map entries for all children of page pPage. Also, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
** pPage contains cells that point to overflow pages, set the pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
** map entries for the overflow pages as well.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
static int setChildPtrmaps(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
  int i;                             /* Counter variable */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1911
  int nCell;                         /* Number of cells in page pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1912
  int rc;                            /* Return code */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
  int isInitOrig = pPage->isInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
  Pgno pgno = pPage->pgno;
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
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
  rc = sqlite3BtreeInitPage(pPage, pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
    goto set_child_ptrmaps_out;
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
  nCell = pPage->nCell;
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
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
    u8 *pCell = findCell(pPage, i);
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
    rc = ptrmapPutOvflPtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
      goto set_child_ptrmaps_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
    }
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
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
      Pgno childPgno = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
    }
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
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
  }
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
set_child_ptrmaps_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
  pPage->isInit = isInitOrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1947
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1948
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
** page, is a pointer to page iFrom. Modify this pointer so that it points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
** iTo. Parameter eType describes the type of pointer to be modified, as 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
** follows:
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
** PTRMAP_BTREE:     pPage is a btree-page. The pointer points at a child 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
**                   page of pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
**                   page pointed to by one of the cells on pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
**                   overflow page in the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
  if( eType==PTRMAP_OVERFLOW2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
    /* The pointer is always the first 4 bytes of the page in this case.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
    if( get4byte(pPage->aData)!=iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      return SQLITE_CORRUPT_BKPT;
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
    put4byte(pPage->aData, iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
    int isInitOrig = pPage->isInit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
    int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
    sqlite3BtreeInitPage(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
    nCell = pPage->nCell;
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
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
      u8 *pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
      if( eType==PTRMAP_OVERFLOW1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
        CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
        sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
        if( info.iOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
          if( iFrom==get4byte(&pCell[info.iOverflow]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
            put4byte(&pCell[info.iOverflow], iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1988
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1989
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
        if( get4byte(pCell)==iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
          put4byte(pCell, iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
    }
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
    if( i==nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2000
      if( eType!=PTRMAP_BTREE || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2001
          get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
        return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
      put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
    pPage->isInit = isInitOrig;
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
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
** Move the open database page pDbPage to location iFreePage in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
** database. The pDbPage reference remains valid.
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
static int relocatePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
  BtShared *pBt,           /* Btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
  MemPage *pDbPage,        /* Open page to move */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
  Pgno iFreePage           /* The location to move pDbPage to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
  Pgno iDbPage = pDbPage->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
  Pager *pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
  int rc;
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
  assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
      eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
  assert( pDbPage->pBt==pBt );
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
  /* Move page iDbPage from its current location to page number iFreePage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
  TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
      iDbPage, iFreePage, iPtrPage, eType));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
  rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
    return rc;
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
  pDbPage->pgno = iFreePage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
  /* If pDbPage was a btree-page, then it may have child pages and/or cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
  ** that point to overflow pages. The pointer map entries for all these
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
  ** pages need to be changed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
  ** If pDbPage is an overflow page, then the first 4 bytes may store a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
  ** pointer to a subsequent overflow page. If this is the case, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
  ** the pointer map needs to be updated for the subsequent overflow page.
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
  if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
    rc = setChildPtrmaps(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
    Pgno nextOvfl = get4byte(pDbPage->aData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
    if( nextOvfl!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
      rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
      }
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
  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
  ** that it points at iFreePage. Also fix the pointer map entry for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
  ** iPtrPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
  if( eType!=PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
    rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
      releasePage(pPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
      return rc;
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
    rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
    releasePage(pPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2087
}
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
/* Forward declaration required by incrVacuumStep(). */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
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
** Perform a single step of an incremental-vacuum. If successful,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
** return SQLITE_OK. If there is no work to do (and therefore no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
** point in calling this function again), return SQLITE_DONE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
** More specificly, this function attempts to re-organize the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
** database so that the last page of the file currently in use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
** is no longer in use.
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
** If the nFin parameter is non-zero, the implementation assumes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
** that the caller will keep calling incrVacuumStep() until
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
** it returns SQLITE_DONE or an error, and that nFin is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
** number of pages the database file will contain after this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
** process is complete.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
static int incrVacuumStep(BtShared *pBt, Pgno nFin){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
  Pgno iLastPg;             /* Last page in the database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
  Pgno nFreeList;           /* Number of pages still on the free-list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
  iLastPg = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
  if( iLastPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
    iLastPg = sqlite3PagerPagecount(pBt->pPager);
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
  if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
    u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
    Pgno iPtrPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
    nFreeList = get4byte(&pBt->pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
    if( nFreeList==0 || nFin==iLastPg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
      return SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
    rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
    if( eType==PTRMAP_ROOTPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2132
      return SQLITE_CORRUPT_BKPT;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
    if( eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
      if( nFin==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
        /* Remove the page from the files free-list. This is not required
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
        ** if nFin is non-zero. In that case, the free-list will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
        ** truncated to zero after this function returns, so it doesn't 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
        ** matter if it still contains some garbage entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2141
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2142
        Pgno iFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
        MemPage *pFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
        rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
        assert( iFreePg==iLastPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
        releasePage(pFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
    } else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
      Pgno iFreePg;             /* Index of free page to move pLastPg to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
      MemPage *pLastPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
      rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
      /* If nFin is zero, this loop runs exactly once and page pLastPg
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
      ** is swapped with the first free page pulled off the free list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
      ** On the other hand, if nFin is greater than zero, then keep
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
      ** looping until a free-page located within the first nFin pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
      ** of the file is found.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
      do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
        MemPage *pFreePg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
        rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
          releasePage(pLastPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
        releasePage(pFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
      }while( nFin!=0 && iFreePg>nFin );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
      assert( iFreePg<iLastPg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
      
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
      rc = sqlite3PagerWrite(pLastPg->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
        rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
      releasePage(pLastPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
      }
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
  pBt->nTrunc = iLastPg - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
  while( pBt->nTrunc==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, pBt->nTrunc) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
    pBt->nTrunc--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
** A write-transaction must be opened before calling this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
** It performs a single unit of work towards an incremental vacuum.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
** If the incremental vacuum is finished after this function has run,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
** SQLITE_DONE is returned. If it is not finished, but no error occured,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
** SQLITE_OK is returned. Otherwise an SQLite error code. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
int sqlite3BtreeIncrVacuum(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
  assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
  if( !pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
    rc = SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
    invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
    rc = incrVacuumStep(pBt, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
}
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
** This routine is called prior to sqlite3PagerCommit when a transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
** is commited for an auto-vacuum database.
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
** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
** the database file should be truncated to during the commit process. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
** i.e. the database has been reorganized so that only the first *pnTrunc
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
** pages are in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
  Pager *pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
  int nRef = sqlite3PagerRefcount(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
#endif
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
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
  invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
  assert(pBt->autoVacuum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
  if( !pBt->incrVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
    Pgno nFin = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
    if( pBt->nTrunc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
      Pgno nFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
      Pgno nPtrmap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
      const int pgsz = pBt->pageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
      Pgno nOrig = sqlite3PagerPagecount(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
      if( PTRMAP_ISPAGE(pBt, nOrig) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
        return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
      if( nOrig==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
        nOrig--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
      nFree = get4byte(&pBt->pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
      nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+pgsz/5)/(pgsz/5);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
      nFin = nOrig - nFree - nPtrmap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
      if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
        nFin--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2261
      while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2262
        nFin--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2263
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2264
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2265
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2266
    while( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2267
      rc = incrVacuumStep(pBt, nFin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2268
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2269
    if( rc==SQLITE_DONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2270
      assert(nFin==0 || pBt->nTrunc==0 || nFin<=pBt->nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2271
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2272
      if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2273
        rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2274
        put4byte(&pBt->pPage1->aData[32], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2275
        put4byte(&pBt->pPage1->aData[36], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2276
        pBt->nTrunc = nFin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2277
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2278
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2279
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2280
      sqlite3PagerRollback(pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2281
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2282
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2283
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2284
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2285
    *pnTrunc = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2286
    pBt->nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2287
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2288
  assert( nRef==sqlite3PagerRefcount(pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2289
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2290
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2291
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2292
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2293
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2294
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2295
** This routine does the first phase of a two-phase commit.  This routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2296
** causes a rollback journal to be created (if it does not already exist)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2297
** and populated with enough information so that if a power loss occurs
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2298
** the database can be restored to its original state by playing back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2299
** the journal.  Then the contents of the journal are flushed out to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2300
** the disk.  After the journal is safely on oxide, the changes to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2301
** database are written into the database file and flushed to oxide.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2302
** At the end of this call, the rollback journal still exists on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2303
** disk and we are still holding all locks, so the transaction has not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2304
** committed.  See sqlite3BtreeCommit() for the second phase of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2305
** commit process.
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
** This call is a no-op if no write-transaction is currently active on pBt.
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
** Otherwise, sync the database file for the btree pBt. zMaster points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2310
** the name of a master journal file that should be written into the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2311
** individual journal file, or is NULL, indicating no master journal file 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2312
** (single database transaction).
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
** When this is called, the master journal should already have been
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2315
** created, populated with this journal pointer and synced to disk.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2316
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2317
** Once this is routine has returned, the only thing required to commit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2318
** the write-transaction for this database file is to delete the journal.
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
int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2321
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2322
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2323
    BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2324
    Pgno nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2325
    sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2326
    pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2327
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2328
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2329
      rc = autoVacuumCommit(pBt, &nTrunc); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2330
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2331
        sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2332
        return rc;
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2335
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2336
    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2337
    sqlite3BtreeLeave(p);
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
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2340
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2341
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
** Commit the transaction currently in progress.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2344
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2345
** This routine implements the second phase of a 2-phase commit.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2346
** sqlite3BtreeSync() routine does the first phase and should be invoked
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2347
** prior to calling this routine.  The sqlite3BtreeSync() routine did
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2348
** all the work of writing information out to disk and flushing the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2349
** contents so that they are written onto the disk platter.  All this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2350
** routine has to do is delete or truncate the rollback journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2351
** (which causes the transaction to commit) and drop locks.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2352
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2353
** This will release the write lock on the database file.  If there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2354
** are no active cursors, it also releases the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2355
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2356
int sqlite3BtreeCommitPhaseTwo(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2357
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2358
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2359
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2360
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2361
  btreeIntegrity(p);
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
  /* If the handle has a write-transaction open, commit the shared-btrees 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2364
  ** transaction and set the shared state to TRANS_READ.
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
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2367
    int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2368
    assert( pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2369
    assert( pBt->nTransaction>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2370
    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2371
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2372
      sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2373
      return rc;
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
    pBt->inTransaction = TRANS_READ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2376
    pBt->inStmt = 0;
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
  unlockAllTables(p);
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
  /* If the handle has any kind of transaction open, decrement the transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2381
  ** count of the shared btree. If the transaction count reaches 0, set
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2382
  ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2383
  ** will unlock the pager.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2384
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2385
  if( p->inTrans!=TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2386
    pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2387
    if( 0==pBt->nTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2388
      pBt->inTransaction = TRANS_NONE;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2391
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2392
  /* Set the handles current transaction state to TRANS_NONE and unlock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2393
  ** the pager if this call closed the only read or write transaction.
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
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2396
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2397
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2398
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2399
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2400
  return SQLITE_OK;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2403
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2404
** Do both phases of a commit.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2405
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2406
int sqlite3BtreeCommit(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2407
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2408
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2409
  rc = sqlite3BtreeCommitPhaseOne(p, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2410
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2411
    rc = sqlite3BtreeCommitPhaseTwo(p);
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
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2414
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2415
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2416
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2417
#ifndef NDEBUG
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
** Return the number of write-cursors open on this handle. This is for use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2420
** in assert() expressions, so it is only compiled if NDEBUG is not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2421
** defined.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2422
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2423
** For the purposes of this routine, a write-cursor is any cursor that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2424
** is capable of writing to the databse.  That means the cursor was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2425
** originally opened for writing and the cursor has not be disabled
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2426
** by having its state changed to CURSOR_FAULT.
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
static int countWriteCursors(BtShared *pBt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2429
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2430
  int r = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2431
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2432
    if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2433
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2434
  return r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2435
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2436
#endif
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
** This routine sets the state to CURSOR_FAULT and the error
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2440
** code to errCode for every cursor on BtShared that pBtree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2441
** references.
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
** Every cursor is tripped, including cursors that belong
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2444
** to other database connections that happen to be sharing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2445
** the cache with pBtree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2446
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2447
** This routine gets called when a rollback occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2448
** All cursors using the same cache must be tripped
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2449
** to prevent them from trying to use the btree after
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2450
** the rollback.  The rollback may have deleted tables
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2451
** or moved root pages, so it is not sufficient to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2452
** save the state of the cursor.  The cursor must be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2453
** invalidated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2454
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2455
void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2456
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2457
  sqlite3BtreeEnter(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2458
  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2459
    clearCursorPosition(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2460
    p->eState = CURSOR_FAULT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2461
    p->skip = errCode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2462
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2463
  sqlite3BtreeLeave(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2464
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2465
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2466
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2467
** Rollback the transaction in progress.  All cursors will be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2468
** invalided by this operation.  Any attempt to use a cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2469
** that was open at the beginning of this operation will result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2470
** in an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2471
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2472
** This will release the write lock on the database file.  If there
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2473
** are no active cursors, it also releases the read lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2474
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2475
int sqlite3BtreeRollback(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2476
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2477
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2478
  MemPage *pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2479
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2480
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2481
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2482
  rc = saveAllCursors(pBt, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2483
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2484
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2485
    /* This is a horrible situation. An IO or malloc() error occured whilst
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2486
    ** trying to save cursor positions. If this is an automatic rollback (as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2487
    ** the result of a constraint, malloc() failure or IO error) then 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2488
    ** the cache may be internally inconsistent (not contain valid trees) so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2489
    ** we cannot simply return the error to the caller. Instead, abort 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2490
    ** all queries that may be using any of the cursors that failed to save.
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
    sqlite3BtreeTripAllCursors(p, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2493
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2494
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2495
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2496
  unlockAllTables(p);
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
  if( p->inTrans==TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2499
    int rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2500
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2501
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2502
    pBt->nTrunc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2503
#endif
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
    assert( TRANS_WRITE==pBt->inTransaction );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2506
    rc2 = sqlite3PagerRollback(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2507
    if( rc2!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2508
      rc = rc2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2509
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2510
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2511
    /* The rollback may have destroyed the pPage1->aData value.  So
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2512
    ** call sqlite3BtreeGetPage() on page 1 again to make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2513
    ** sure pPage1->aData is set correctly. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2514
    if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2515
      releasePage(pPage1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2516
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2517
    assert( countWriteCursors(pBt)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2518
    pBt->inTransaction = TRANS_READ;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2519
  }
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( p->inTrans!=TRANS_NONE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2522
    assert( pBt->nTransaction>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2523
    pBt->nTransaction--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2524
    if( 0==pBt->nTransaction ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2525
      pBt->inTransaction = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2526
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2529
  p->inTrans = TRANS_NONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2530
  pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2531
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2532
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2533
  btreeIntegrity(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2534
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2535
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2536
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2537
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
** Start a statement subtransaction.  The subtransaction can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2540
** can be rolled back independently of the main transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2541
** You must start a transaction before starting a subtransaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2542
** The subtransaction is ended automatically if the main transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2543
** commits or rolls back.
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
** Only one subtransaction may be active at a time.  It is an error to try
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2546
** to start a new subtransaction if another subtransaction is already active.
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
** Statement subtransactions are used around individual SQL statements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2549
** that are contained within a BEGIN...COMMIT block.  If a constraint
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2550
** error occurs within the statement, the effect of that one statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2551
** can be rolled back without having to rollback the entire transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2552
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2553
int sqlite3BtreeBeginStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2554
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2555
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2556
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2557
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2558
  if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2559
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2560
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2561
    assert( pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2562
    rc = pBt->readOnly ? SQLITE_OK : sqlite3PagerStmtBegin(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2563
    pBt->inStmt = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2564
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2565
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2566
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2567
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2568
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2569
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2570
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2571
** Commit the statment subtransaction currently in progress.  If no
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2572
** subtransaction is active, this is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2573
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2574
int sqlite3BtreeCommitStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2575
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2576
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2577
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2578
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2579
  if( pBt->inStmt && !pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2580
    rc = sqlite3PagerStmtCommit(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2581
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2582
    rc = SQLITE_OK;
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
  pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2585
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2586
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2587
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2588
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
** Rollback the active statement subtransaction.  If no subtransaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2591
** is active this routine is a no-op.
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
** All cursors will be invalidated by this operation.  Any attempt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2594
** to use a cursor that was open at the beginning of this operation
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2595
** will result in an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2596
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2597
int sqlite3BtreeRollbackStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2598
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2599
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2600
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2601
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2602
  if( pBt->inStmt && !pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2603
    rc = sqlite3PagerStmtRollback(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2604
    assert( countWriteCursors(pBt)==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2605
    pBt->inStmt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2606
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2607
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2608
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2609
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2610
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2611
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2612
** Default key comparison function to be used if no comparison function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2613
** is specified on the sqlite3BtreeCursor() call.
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
static int dfltCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2616
  void *NotUsed,             /* User data is not used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2617
  int n1, const void *p1,    /* First key to compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2618
  int n2, const void *p2     /* Second key to compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2619
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2620
  int c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2621
  c = memcmp(p1, p2, n1<n2 ? n1 : n2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2622
  if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2623
    c = n1 - n2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2624
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2625
  return c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2626
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2627
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
** Create a new cursor for the BTree whose root is on the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2630
** iTable.  The act of acquiring a cursor gets a read lock on 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2631
** the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2632
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2633
** If wrFlag==0, then the cursor can only be used for reading.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2634
** If wrFlag==1, then the cursor can be used for reading or for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2635
** writing if other conditions for writing are also met.  These
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2636
** are the conditions that must be met in order for writing to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2637
** be allowed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2638
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2639
** 1:  The cursor must have been opened with wrFlag==1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2640
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2641
** 2:  Other database connections that share the same pager cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2642
**     but which are not in the READ_UNCOMMITTED state may not have
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2643
**     cursors open with wrFlag==0 on the same table.  Otherwise
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2644
**     the changes made by this write cursor would be visible to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2645
**     the read cursors in the other database connection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2646
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2647
** 3:  The database must be writable (not on read-only media)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2648
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2649
** 4:  There must be an active transaction.
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
** No checking is done to make sure that page iTable really is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2652
** root page of a b-tree.  If it is not, then the cursor acquired
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2653
** will not work correctly.
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
** The comparison function must be logically the same for every cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2656
** on a particular table.  Changing the comparison function will result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2657
** in incorrect operations.  If the comparison function is NULL, a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2658
** default comparison function is used.  The comparison function is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2659
** always ignored for INTKEY tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2660
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2661
static int btreeCursor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2662
  Btree *p,                                   /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2663
  int iTable,                                 /* Root page of table to open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2664
  int wrFlag,                                 /* 1 to write. 0 read-only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2665
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2666
  void *pArg,                                 /* First arg to xCompare() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2667
  BtCursor **ppCur                            /* Write new cursor here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2668
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2669
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2670
  BtCursor *pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2671
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2673
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2674
  *ppCur = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2675
  if( wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2676
    if( pBt->readOnly ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2677
      return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2678
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2679
    if( checkReadLocks(p, iTable, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2680
      return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2681
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2684
  if( pBt->pPage1==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2685
    rc = lockBtreeWithRetry(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2686
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2687
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2688
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2689
    if( pBt->readOnly && wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2690
      return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2691
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2692
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2693
  pCur = (BtCursor*)sqlite3MallocZero( sizeof(*pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2694
  if( pCur==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2695
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2696
    goto create_cursor_exception;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2698
  pCur->pgnoRoot = (Pgno)iTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2699
  if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2700
    rc = SQLITE_EMPTY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2701
    goto create_cursor_exception;
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
  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2704
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2705
    goto create_cursor_exception;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2706
  }
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
  /* Now that no other errors can occur, finish filling in the BtCursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2709
  ** variables, link the cursor into the BtShared list and set *ppCur (the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2710
  ** output argument to this function).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2711
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2712
  pCur->xCompare = xCmp ? xCmp : dfltCompare;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2713
  pCur->pArg = pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2714
  pCur->pBtree = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2715
  pCur->pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2716
  pCur->wrFlag = wrFlag;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2717
  pCur->pNext = pBt->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2718
  if( pCur->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2719
    pCur->pNext->pPrev = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2720
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2721
  pBt->pCursor = pCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2722
  pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2723
  *ppCur = pCur;
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
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2726
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2727
create_cursor_exception:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2728
  if( pCur ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2729
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2730
    sqlite3_free(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2731
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2732
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2733
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2734
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2735
int sqlite3BtreeCursor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2736
  Btree *p,                                   /* The btree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2737
  int iTable,                                 /* Root page of table to open */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2738
  int wrFlag,                                 /* 1 to write. 0 read-only */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2739
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2740
  void *pArg,                                 /* First arg to xCompare() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2741
  BtCursor **ppCur                            /* Write new cursor here */
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
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2744
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2745
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2746
  rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2747
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2748
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2749
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2753
** Close a cursor.  The read lock on the database file is released
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2754
** when the last cursor is closed.
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
int sqlite3BtreeCloseCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2757
  BtShared *pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2758
  Btree *pBtree = pCur->pBtree;
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
  sqlite3BtreeEnter(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2761
  pBt->db = pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2762
  clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2763
  if( pCur->pPrev ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2764
    pCur->pPrev->pNext = pCur->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2765
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2766
    pBt->pCursor = pCur->pNext;
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
  if( pCur->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2769
    pCur->pNext->pPrev = pCur->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2770
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2771
  releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2772
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2773
  invalidateOverflowCache(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2774
  sqlite3_free(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2775
  sqlite3BtreeLeave(pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2776
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2777
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2778
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2779
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2780
** Make a temporary cursor by filling in the fields of pTempCur.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2781
** The temporary cursor is not on the cursor list for the Btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2782
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2783
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2784
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2785
  memcpy(pTempCur, pCur, sizeof(*pCur));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2786
  pTempCur->pNext = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2787
  pTempCur->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2788
  if( pTempCur->pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2789
    sqlite3PagerRef(pTempCur->pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2790
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2793
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2794
** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2795
** function above.
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
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2798
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2799
  if( pCur->pPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2800
    sqlite3PagerUnref(pCur->pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2801
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2802
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2803
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
** Make sure the BtCursor* given in the argument has a valid
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2806
** BtCursor.info structure.  If it is not already valid, call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2807
** sqlite3BtreeParseCell() to fill it in.
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
** BtCursor.info is a cache of the information in the current cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2810
** Using this cache reduces the number of calls to sqlite3BtreeParseCell().
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
** 2007-06-25:  There is a bug in some versions of MSVC that cause the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2813
** compiler to crash when getCellInfo() is implemented as a macro.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2814
** But there is a measureable speed advantage to using the macro on gcc
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2815
** (when less compiler optimizations like -Os or -O0 are used and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2816
** compiler is not doing agressive inlining.)  So we use a real function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2817
** for MSVC and a macro for everything else.  Ticket #2457.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2818
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2819
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2820
  static void assertCellInfo(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2821
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2822
    memset(&info, 0, sizeof(info));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2823
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2824
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2825
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2826
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2827
  #define assertCellInfo(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2828
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2829
#ifdef _MSC_VER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2830
  /* Use a real function in MSVC to work around bugs in that compiler. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2831
  static void getCellInfo(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2832
    if( pCur->info.nSize==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2833
      sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2834
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2835
      assertCellInfo(pCur);
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
#else /* if not _MSC_VER */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2839
  /* Use a macro in all other compilers so that the function is inlined */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2840
#define getCellInfo(pCur)                                               \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2841
  if( pCur->info.nSize==0 ){                                            \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2842
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);         \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2843
  }else{                                                                \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2844
    assertCellInfo(pCur);                                               \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2845
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2846
#endif /* _MSC_VER */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2847
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
** Set *pSize to the size of the buffer needed to hold the value of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2850
** the key for the current entry.  If the cursor is not pointing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2851
** to a valid entry, *pSize is set to 0. 
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
** For a table with the INTKEY flag set, this routine returns the key
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2854
** itself, not the number of bytes in the key.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2855
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2856
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2857
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2859
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2860
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2861
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2862
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2863
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2864
      *pSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2865
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2866
      getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2867
      *pSize = pCur->info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2868
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2869
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2870
  return rc;
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
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
** Set *pSize to the number of bytes of data in the entry the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2875
** cursor currently points to.  Always return SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2876
** Failure is not possible.  If the cursor is not currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2877
** pointing to an entry (which can happen, for example, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2878
** the database is empty) then *pSize is set to 0.
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
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2881
  int rc;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2884
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2885
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2886
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2887
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2888
      /* Not pointing at a valid entry - set *pSize to 0. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2889
      *pSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2890
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2891
      getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2892
      *pSize = pCur->info.nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2893
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2894
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2895
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2898
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2899
** Given the page number of an overflow page in the database (parameter
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2900
** ovfl), this function finds the page number of the next page in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2901
** linked list of overflow pages. If possible, it uses the auto-vacuum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2902
** pointer-map data instead of reading the content of page ovfl to do so. 
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
** If an error occurs an SQLite error code is returned. Otherwise:
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
** Unless pPgnoNext is NULL, the page number of the next overflow 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2907
** page in the linked list is written to *pPgnoNext. If page ovfl
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2908
** is the last page in its linked list, *pPgnoNext is set to zero. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2909
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2910
** If ppPage is not NULL, *ppPage is set to the MemPage* handle
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2911
** for page ovfl. The underlying pager page may have been requested
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2912
** with the noContent flag set, so the page data accessable via
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2913
** this handle may not be trusted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2914
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2915
static int getOverflowPage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2916
  BtShared *pBt, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2917
  Pgno ovfl,                   /* Overflow page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2918
  MemPage **ppPage,            /* OUT: MemPage handle */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2919
  Pgno *pPgnoNext              /* OUT: Next overflow page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2920
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2921
  Pgno next = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2922
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2923
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2924
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2925
  /* One of these must not be NULL. Otherwise, why call this function? */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2926
  assert(ppPage || pPgnoNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2928
  /* If pPgnoNext is NULL, then this function is being called to obtain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2929
  ** a MemPage* reference only. No page-data is required in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2930
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2931
  if( !pPgnoNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2932
    return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2933
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2934
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2935
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2936
  /* Try to find the next page in the overflow list using the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2937
  ** autovacuum pointer-map pages. Guess that the next page in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2938
  ** the overflow list is page number (ovfl+1). If that guess turns 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2939
  ** out to be wrong, fall back to loading the data of page 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2940
  ** number ovfl to determine the next page number.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2941
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2942
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2943
    Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2944
    Pgno iGuess = ovfl+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2945
    u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2946
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2947
    while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2948
      iGuess++;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2951
    if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2952
      rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2953
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2954
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2955
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2956
      if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2957
        next = iGuess;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2958
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2959
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2960
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2961
#endif
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( next==0 || ppPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2964
    MemPage *pPage = 0;
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
    rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2967
    assert(rc==SQLITE_OK || pPage==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2968
    if( next==0 && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2969
      next = get4byte(pPage->aData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2970
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2971
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2972
    if( ppPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2973
      *ppPage = pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2974
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2975
      releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2976
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2977
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2978
  *pPgnoNext = next;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2979
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2980
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2983
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2984
** Copy data from a buffer to a page, or from a page to a buffer.
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
** pPayload is a pointer to data stored on database page pDbPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2987
** If argument eOp is false, then nByte bytes of data are copied
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2988
** from pPayload to the buffer pointed at by pBuf. If eOp is true,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2989
** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2990
** of data are copied from the buffer pBuf to pPayload.
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
** SQLITE_OK is returned on success, otherwise an error code.
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
static int copyPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2995
  void *pPayload,           /* Pointer to page data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2996
  void *pBuf,               /* Pointer to buffer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2997
  int nByte,                /* Number of bytes to copy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2998
  int eOp,                  /* 0 -> copy from page, 1 -> copy to page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2999
  DbPage *pDbPage           /* Page containing pPayload */
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
  if( eOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3002
    /* Copy data from buffer to page (a write operation) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3003
    int rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3004
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3005
      return rc;
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
    memcpy(pPayload, pBuf, nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3008
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3009
    /* Copy data from page to buffer (a read operation) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3010
    memcpy(pBuf, pPayload, nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3011
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3012
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3013
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3014
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3015
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3016
** This function is used to read or overwrite payload information
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3017
** for the entry that the pCur cursor is pointing to. If the eOp
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3018
** parameter is 0, this is a read operation (data copied into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3019
** buffer pBuf). If it is non-zero, a write (data copied from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3020
** buffer pBuf).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3021
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3022
** A total of "amt" bytes are read or written beginning at "offset".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3023
** Data is read to or from the buffer pBuf.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3024
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3025
** This routine does not make a distinction between key and data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3026
** It just reads or writes bytes from the payload area.  Data might 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3027
** appear on the main page or be scattered out on multiple overflow 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3028
** pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3029
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3030
** If the BtCursor.isIncrblobHandle flag is set, and the current
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3031
** cursor entry uses one or more overflow pages, this function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3032
** allocates space for and lazily popluates the overflow page-list 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3033
** cache array (BtCursor.aOverflow). Subsequent calls use this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3034
** cache to make seeking to the supplied offset more efficient.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3035
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3036
** Once an overflow page-list cache has been allocated, it may be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3037
** invalidated if some other cursor writes to the same table, or if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3038
** the cursor is moved to a different row. Additionally, in auto-vacuum
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3039
** mode, the following events may invalidate an overflow page-list cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3040
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3041
**   * An incremental vacuum,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3042
**   * A commit in auto_vacuum="full" mode,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3043
**   * Creating a table (may require moving an overflow page).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3044
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3045
static int accessPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3046
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3047
  int offset,          /* Begin reading this far into payload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3048
  int amt,             /* Read this many bytes */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3049
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3050
  int skipKey,         /* offset begins at data if this is true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3051
  int eOp              /* zero to read. non-zero to write. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3052
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3053
  unsigned char *aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3054
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3055
  u32 nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3056
  int iIdx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3057
  MemPage *pPage = pCur->pPage;     /* Btree page of current cursor entry */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3058
  BtShared *pBt;                   /* Btree this cursor belongs to */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3059
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3060
  assert( pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3061
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3062
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3063
  assert( offset>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3064
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3065
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3066
  getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3067
  aPayload = pCur->info.pCell + pCur->info.nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3068
  nKey = (pPage->intKey ? 0 : pCur->info.nKey);
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
  if( skipKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3071
    offset += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3072
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3073
  if( offset+amt > nKey+pCur->info.nData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3074
    /* Trying to read or write past the end of the data is an error */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3075
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3076
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3077
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3078
  /* Check if data must be read/written to/from the btree page itself. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3079
  if( offset<pCur->info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3080
    int a = amt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3081
    if( a+offset>pCur->info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3082
      a = pCur->info.nLocal - offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3083
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3084
    rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3085
    offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3086
    pBuf += a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3087
    amt -= a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3088
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3089
    offset -= pCur->info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3090
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3091
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3092
  pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3093
  if( rc==SQLITE_OK && amt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3094
    const int ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3095
    Pgno nextPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3096
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3097
    nextPage = get4byte(&aPayload[pCur->info.nLocal]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3098
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3099
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3100
    /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3101
    ** has not been allocated, allocate it now. The array is sized at
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3102
    ** one entry for each overflow page in the overflow chain. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3103
    ** page number of the first overflow page is stored in aOverflow[0],
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3104
    ** etc. A value of 0 in the aOverflow[] array means "not yet known"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3105
    ** (the cache is lazily populated).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3106
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3107
    if( pCur->isIncrblobHandle && !pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3108
      int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3109
      pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3110
      if( nOvfl && !pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3111
        rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3112
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3113
    }
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
    /* If the overflow page-list cache has been allocated and the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3116
    ** entry for the first required overflow page is valid, skip
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3117
    ** directly to it.
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
    if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3120
      iIdx = (offset/ovflSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3121
      nextPage = pCur->aOverflow[iIdx];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3122
      offset = (offset%ovflSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3123
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3124
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3125
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3126
    for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3127
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3128
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3129
      /* If required, populate the overflow page-list cache. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3130
      if( pCur->aOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3131
        assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3132
        pCur->aOverflow[iIdx] = nextPage;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3135
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3136
      if( offset>=ovflSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3137
        /* The only reason to read this page is to obtain the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3138
        ** number for the next page in the overflow chain. The page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3139
        ** data is not required. So first try to lookup the overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3140
        ** page-list cache, if any, then fall back to the getOverflowPage()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3141
        ** function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3142
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3143
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3144
        if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3145
          nextPage = pCur->aOverflow[iIdx+1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3146
        } else 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3147
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3148
          rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3149
        offset -= ovflSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3150
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3151
        /* Need to read this page properly. It contains some of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3152
        ** range of data that is being read (eOp==0) or written (eOp!=0).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3153
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3154
        DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3155
        int a = amt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3156
        rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3157
        if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3158
          aPayload = (unsigned char*)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3159
          nextPage = get4byte(aPayload);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3160
          if( a + offset > ovflSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3161
            a = ovflSize - offset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3162
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3163
          rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3164
          sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3165
          offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3166
          amt -= a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3167
          pBuf += a;
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
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3170
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3171
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3172
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3173
  if( rc==SQLITE_OK && amt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3174
    return SQLITE_CORRUPT_BKPT;
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
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3179
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3180
** Read part of the key associated with cursor pCur.  Exactly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3181
** "amt" bytes will be transfered into pBuf[].  The transfer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3182
** begins at "offset".
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
** Return SQLITE_OK on success or an error code if anything goes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3185
** wrong.  An error is returned if "offset+amt" is larger than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3186
** the available payload.
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
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3189
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3190
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3191
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3192
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3193
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3194
    assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3195
    assert( pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3196
    if( pCur->pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3197
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3198
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3199
    assert( pCur->pPage->intKey==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3200
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3201
    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3202
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3203
  return rc;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3207
** Read part of the data associated with cursor pCur.  Exactly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3208
** "amt" bytes will be transfered into pBuf[].  The transfer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3209
** begins at "offset".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3210
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3211
** Return SQLITE_OK on success or an error code if anything goes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3212
** wrong.  An error is returned if "offset+amt" is larger than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3213
** the available payload.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3214
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3215
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3216
  int rc;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3219
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3220
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3221
    assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3222
    assert( pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3223
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3224
    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3225
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3226
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3227
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3230
** Return a pointer to payload information from the entry that the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3231
** pCur cursor is pointing to.  The pointer is to the beginning of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3232
** the key if skipKey==0 and it points to the beginning of data if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3233
** skipKey==1.  The number of bytes of available key/data is written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3234
** into *pAmt.  If *pAmt==0, then the value returned will not be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3235
** a valid pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3236
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3237
** This routine is an optimization.  It is common for the entire key
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3238
** and data to fit on the local page and for there to be no overflow
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3239
** pages.  When that is so, this routine can be used to access the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3240
** key and data without making a copy.  If the key and/or data spills
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3241
** onto overflow pages, then accessPayload() must be used to reassembly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3242
** the key/data and copy it into a preallocated buffer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3243
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3244
** The pointer returned by this routine looks directly into the cached
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3245
** page of the database.  The data might change or move the next time
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3246
** any btree routine is called.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3247
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3248
static const unsigned char *fetchPayload(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3249
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3250
  int *pAmt,           /* Write the number of available bytes here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3251
  int skipKey          /* read beginning at data if this is true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3252
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3253
  unsigned char *aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3254
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3255
  u32 nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3256
  int nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3257
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3258
  assert( pCur!=0 && pCur->pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3259
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3260
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3261
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3262
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3263
  getCellInfo(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3264
  aPayload = pCur->info.pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3265
  aPayload += pCur->info.nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3266
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3267
    nKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3268
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3269
    nKey = pCur->info.nKey;
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
  if( skipKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3272
    aPayload += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3273
    nLocal = pCur->info.nLocal - nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3274
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3275
    nLocal = pCur->info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3276
    if( nLocal>nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3277
      nLocal = nKey;
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
  *pAmt = nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3281
  return aPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3282
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3283
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3284
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3285
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3286
** For the entry that cursor pCur is point to, return as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3287
** many bytes of the key or data as are available on the local
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3288
** b-tree page.  Write the number of available bytes into *pAmt.
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
** The pointer returned is ephemeral.  The key/data may move
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3291
** or be destroyed on the next call to any Btree routine,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3292
** including calls from other threads against the same cache.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3293
** Hence, a mutex on the BtShared should be held prior to calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3294
** this routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3295
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3296
** These routines is used to get quick access to key and data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3297
** in the common case where no overflow pages are used.
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
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3300
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3301
  if( pCur->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3302
    return (const void*)fetchPayload(pCur, pAmt, 0);
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
  return 0;
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
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3307
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3308
  if( pCur->eState==CURSOR_VALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3309
    return (const void*)fetchPayload(pCur, pAmt, 1);
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
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3312
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3313
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3316
** Move the cursor down to a new child page.  The newPgno argument is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3317
** page number of the child page to move to.
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
static int moveToChild(BtCursor *pCur, u32 newPgno){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3320
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3321
  MemPage *pNewPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3322
  MemPage *pOldPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3323
  BtShared *pBt = pCur->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3324
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3325
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3326
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3327
  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3328
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3329
  pNewPage->idxParent = pCur->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3330
  pOldPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3331
  pOldPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3332
  releasePage(pOldPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3333
  pCur->pPage = pNewPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3334
  pCur->idx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3335
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3336
  if( pNewPage->nCell<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3337
    return SQLITE_CORRUPT_BKPT;
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
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3340
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3341
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3342
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3343
** Return true if the page is the virtual root of its table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3344
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3345
** The virtual root page is the root page for most tables.  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3346
** for the table rooted on page 1, sometime the real root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3347
** is empty except for the right-pointer.  In such cases the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3348
** virtual root page is the page that the right-pointer of page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3349
** 1 is pointing to.
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
int sqlite3BtreeIsRootPage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3352
  MemPage *pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3353
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3354
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3355
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3356
  if( pParent==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3357
  if( pParent->pgno>1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3358
  if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3359
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3360
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3361
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
** Move the cursor up to the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3364
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3365
** pCur->idx is set to the cell index that contains the pointer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3366
** to the page we are coming from.  If we are coming from the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3367
** right-most child page then pCur->idx is set to one more than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3368
** the largest cell index.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3369
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3370
void sqlite3BtreeMoveToParent(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3371
  MemPage *pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3372
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3373
  int idxParent;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3376
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3377
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3378
  assert( pPage!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3379
  assert( !sqlite3BtreeIsRootPage(pPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3380
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3381
  assert( pParent!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3382
  idxParent = pPage->idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3383
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3384
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3385
  pCur->pPage = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3386
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3387
  assert( pParent->idxShift==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3388
  pCur->idx = idxParent;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3391
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3392
** Move the cursor to the root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3393
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3394
static int moveToRoot(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3395
  MemPage *pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3396
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3397
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3398
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3399
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3400
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3401
  assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3402
  assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3403
  assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3404
  if( pCur->eState>=CURSOR_REQUIRESEEK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3405
    if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3406
      return pCur->skip;
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
    clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3409
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3410
  pRoot = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3411
  if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3412
    assert( pRoot->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3413
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3414
    if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3415
      SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
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
      pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3418
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3419
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3420
    releasePage(pCur->pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3421
    pCur->pPage = pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3422
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3423
  pCur->idx = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3424
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3425
  if( pRoot->nCell==0 && !pRoot->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3426
    Pgno subpage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3427
    assert( pRoot->pgno==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3428
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3429
    assert( subpage>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3430
    pCur->eState = CURSOR_VALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3431
    rc = moveToChild(pCur, subpage);
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
  pCur->eState = ((pCur->pPage->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3434
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3435
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3436
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3437
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3438
** Move the cursor down to the left-most leaf entry beneath the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3439
** entry to which it is currently pointing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3440
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3441
** The left-most leaf is the one with the smallest key - the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3442
** in ascending order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3443
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3444
static int moveToLeftmost(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3445
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3446
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3447
  MemPage *pPage;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3450
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3451
  while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3452
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3453
    pgno = get4byte(findCell(pPage, pCur->idx));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3454
    rc = moveToChild(pCur, pgno);
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
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3457
}
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
** Move the cursor down to the right-most leaf entry beneath the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3461
** page to which it is currently pointing.  Notice the difference
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3462
** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3463
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3464
** finds the right-most entry beneath the *page*.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3465
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3466
** The right-most entry is the one with the largest key - the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3467
** key in ascending order.
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
static int moveToRightmost(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3470
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3471
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3472
  MemPage *pPage;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3475
  assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3476
  while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3477
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3478
    pCur->idx = pPage->nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3479
    rc = moveToChild(pCur, pgno);
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
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3482
    pCur->idx = pPage->nCell - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3483
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3484
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3485
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3486
}
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
/* Move the cursor to the first entry in the table.  Return SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3489
** on success.  Set *pRes to 0 if the cursor actually points to something
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3490
** or set *pRes to 1 if the table is empty.
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
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3493
  int rc;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3496
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3497
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3498
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3499
    if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3500
      assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3501
      *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3502
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3503
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3504
      assert( pCur->pPage->nCell>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3505
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3506
      rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3507
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3508
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3509
  return rc;
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3512
/* Move the cursor to the last entry in the table.  Return SQLITE_OK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3513
** on success.  Set *pRes to 0 if the cursor actually points to something
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3514
** or set *pRes to 1 if the table is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3515
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3516
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3517
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3518
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3519
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3520
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3521
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3522
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3523
    if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3524
      assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3525
      *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3526
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3527
      assert( pCur->eState==CURSOR_VALID );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3528
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3529
      rc = moveToRightmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3530
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3531
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3532
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3533
}
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
/* Move the cursor so that it points to an entry near pKey/nKey.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3536
** Return a success code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3537
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3538
** For INTKEY tables, only the nKey parameter is used.  pKey is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3539
** ignored.  For other tables, nKey is the number of bytes of data
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3540
** in pKey.  The comparison function specified when the cursor was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3541
** created is used to compare keys.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3542
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3543
** If an exact match is not found, then the cursor is always
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3544
** left pointing at a leaf page which would hold the entry if it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3545
** were present.  The cursor might point to an entry that comes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3546
** before or after the key.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3547
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3548
** The result of comparing the key with the entry to which the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3549
** cursor is written to *pRes if pRes!=NULL.  The meaning of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3550
** this value is as follows:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3552
**     *pRes<0      The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3553
**                  is smaller than pKey or if the table is empty
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3554
**                  and the cursor is therefore left point to nothing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3555
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3556
**     *pRes==0     The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3557
**                  exactly matches pKey.
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
**     *pRes>0      The cursor is left pointing at an entry that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3560
**                  is larger than pKey.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3561
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3562
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3563
int sqlite3BtreeMoveto(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3564
  BtCursor *pCur,        /* The cursor to be moved */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3565
  const void *pKey,      /* The key content for indices.  Not used by tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3566
  i64 nKey,              /* Size of pKey.  Or the key for tables */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3567
  int biasRight,         /* If true, bias the search to the high end */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3568
  int *pRes              /* Search result flag */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3569
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3570
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3571
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3572
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3573
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3574
  rc = moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3575
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3576
    return rc;
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
  assert( pCur->pPage );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3579
  assert( pCur->pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3580
  if( pCur->eState==CURSOR_INVALID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3581
    *pRes = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3582
    assert( pCur->pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3583
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3584
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3585
  for(;;){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3586
    int lwr, upr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3587
    Pgno chldPg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3588
    MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3589
    int c = -1;  /* pRes return if table is empty must be -1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3590
    lwr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3591
    upr = pPage->nCell-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3592
    if( !pPage->intKey && pKey==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3593
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3594
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3595
    if( biasRight ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3596
      pCur->idx = upr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3597
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3598
      pCur->idx = (upr+lwr)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3599
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3600
    if( lwr<=upr ) for(;;){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3601
      void *pCellKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3602
      i64 nCellKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3603
      pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3604
      if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3605
        u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3606
        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3607
        if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3608
          u32 dummy;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3609
          pCell += getVarint32(pCell, &dummy);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3610
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3611
        getVarint(pCell, (u64 *)&nCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3612
        if( nCellKey<nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3613
          c = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3614
        }else if( nCellKey>nKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3615
          c = +1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3616
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3617
          c = 0;
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
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3620
        int available;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3621
        pCellKey = (void *)fetchPayload(pCur, &available, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3622
        nCellKey = pCur->info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3623
        if( available>=nCellKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3624
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3625
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3626
          pCellKey = sqlite3_malloc( nCellKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3627
          if( pCellKey==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3628
          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3629
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3630
          sqlite3_free(pCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3631
          if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3632
            return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3633
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3634
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3635
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3636
      if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3637
        if( pPage->leafData && !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3638
          lwr = pCur->idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3639
          upr = lwr - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3640
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3641
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3642
          if( pRes ) *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3643
          return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3644
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3645
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3646
      if( c<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3647
        lwr = pCur->idx+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3648
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3649
        upr = pCur->idx-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3650
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3651
      if( lwr>upr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3652
        break;
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
      pCur->idx = (lwr+upr)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3655
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3656
    assert( lwr==upr+1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3657
    assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3658
    if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3659
      chldPg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3660
    }else if( lwr>=pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3661
      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3662
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3663
      chldPg = get4byte(findCell(pPage, lwr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3664
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3665
    if( chldPg==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3666
      assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3667
      if( pRes ) *pRes = c;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3668
      return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3669
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3670
    pCur->idx = lwr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3671
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3672
    rc = moveToChild(pCur, chldPg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3673
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3674
      return rc;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3677
  /* NOT REACHED */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3678
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3679
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3680
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
** Return TRUE if the cursor is not pointing at an entry of the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3683
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3684
** TRUE will be returned after a call to sqlite3BtreeNext() moves
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3685
** past the last entry in the table or sqlite3BtreePrev() moves past
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3686
** the first entry.  TRUE is also returned if the table is empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3687
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3688
int sqlite3BtreeEof(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3689
  /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3690
  ** have been deleted? This API will need to change to return an error code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3691
  ** as well as the boolean result value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3692
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3693
  return (CURSOR_VALID!=pCur->eState);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3694
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3695
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3696
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3697
** Return the database connection handle for a cursor.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3698
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3699
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3700
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3701
  return pCur->pBtree->db;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3705
** Advance the cursor to the next entry in the database.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3706
** successful then set *pRes=0.  If the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3707
** was already pointing to the last entry in the database before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3708
** this routine was called, then set *pRes=1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3709
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3710
static int btreeNext(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3711
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3712
  MemPage *pPage;
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
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3715
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3716
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3717
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3718
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3719
  assert( pRes!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3720
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3721
  if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3722
    *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3723
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3724
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3725
  if( pCur->skip>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3726
    pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3727
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3728
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3729
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3730
  pCur->skip = 0;
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
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3733
  assert( pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3734
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3735
  pCur->idx++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3736
  pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3737
  if( pCur->idx>=pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3738
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3739
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3740
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3741
      rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3742
      *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3743
      return rc;
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
    do{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3746
      if( sqlite3BtreeIsRootPage(pPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3747
        *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3748
        pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3749
        return SQLITE_OK;
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
      sqlite3BtreeMoveToParent(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3752
      pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3753
    }while( pCur->idx>=pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3754
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3755
    if( pPage->leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3756
      rc = sqlite3BtreeNext(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3757
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3758
      rc = SQLITE_OK;
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
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3761
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3762
  *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3763
  if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3764
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3765
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3766
  rc = moveToLeftmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3767
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3768
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3769
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3770
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3771
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3772
  rc = btreeNext(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3773
  return rc;
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
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
** Step the cursor to the back to the previous entry in the database.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3779
** successful then set *pRes=0.  If the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3780
** was already pointing to the first entry in the database before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3781
** this routine was called, then set *pRes=1.
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
static int btreePrevious(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3784
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3785
  Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3786
  MemPage *pPage;
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( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3789
  rc = restoreOrClearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3790
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3791
    return rc;
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
  if( CURSOR_INVALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3794
    *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3795
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3796
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3797
  if( pCur->skip<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3798
    pCur->skip = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3799
    *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3800
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3801
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3802
  pCur->skip = 0;
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
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3805
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3806
  assert( pCur->idx>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3807
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3808
    pgno = get4byte( findCell(pPage, pCur->idx) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3809
    rc = moveToChild(pCur, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3810
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3811
      return rc;
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
    rc = moveToRightmost(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3814
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3815
    while( pCur->idx==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3816
      if( sqlite3BtreeIsRootPage(pPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3817
        pCur->eState = CURSOR_INVALID;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3818
        *pRes = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3819
        return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3820
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3821
      sqlite3BtreeMoveToParent(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3822
      pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3823
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3824
    pCur->idx--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3825
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3826
    if( pPage->leafData && !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3827
      rc = sqlite3BtreePrevious(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3828
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3829
      rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3830
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3831
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3832
  *pRes = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3833
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3834
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3835
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3836
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3837
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3838
  rc = btreePrevious(pCur, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3839
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3840
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3841
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
** Allocate a new page from the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3844
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3845
** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3846
** has already been called on the new page.)  The new page has also
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3847
** been referenced and the calling routine is responsible for calling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3848
** sqlite3PagerUnref() on the new page when it is done.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3849
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3850
** SQLITE_OK is returned on success.  Any other return value indicates
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3851
** an error.  *ppPage and *pPgno are undefined in the event of an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3852
** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3853
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3854
** If the "nearby" parameter is not 0, then a (feeble) effort is made to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3855
** locate a page close to the page number "nearby".  This can be used in an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3856
** attempt to keep related pages close to each other in the database file,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3857
** which in turn can make database access faster.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3858
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3859
** If the "exact" parameter is not 0, and the page-number nearby exists 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3860
** anywhere on the free-list, then it is guarenteed to be returned. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3861
** is only used by auto-vacuum databases when allocating a new table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3862
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3863
static int allocateBtreePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3864
  BtShared *pBt, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3865
  MemPage **ppPage, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3866
  Pgno *pPgno, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3867
  Pgno nearby,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3868
  u8 exact
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3869
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3870
  MemPage *pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3871
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3872
  int n;     /* Number of pages on the freelist */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3873
  int k;     /* Number of leaves on the trunk of the freelist */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3874
  MemPage *pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3875
  MemPage *pPrevTrunk = 0;
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
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3878
  pPage1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3879
  n = get4byte(&pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3880
  if( n>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3881
    /* There are pages on the freelist.  Reuse one of those pages. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3882
    Pgno iTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3883
    u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3884
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3885
    /* If the 'exact' parameter was true and a query of the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3886
    ** shows that the page 'nearby' is somewhere on the free-list, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3887
    ** the entire-list will be searched for that page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3888
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3889
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3890
    if( exact && nearby<=sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3891
      u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3892
      assert( nearby>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3893
      assert( pBt->autoVacuum );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3894
      rc = ptrmapGet(pBt, nearby, &eType, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3895
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3896
      if( eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3897
        searchList = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3898
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3899
      *pPgno = nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3900
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3901
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3902
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3903
    /* Decrement the free-list count by 1. Set iTrunk to the index of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3904
    ** first free-list trunk page. iPrevTrunk is initially 1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3905
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3906
    rc = sqlite3PagerWrite(pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3907
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3908
    put4byte(&pPage1->aData[36], n-1);
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 code within this loop is run only once if the 'searchList' variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3911
    ** is not true. Otherwise, it runs once for each trunk-page on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3912
    ** free-list until the page 'nearby' is located.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3913
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3914
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3915
      pPrevTrunk = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3916
      if( pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3917
        iTrunk = get4byte(&pPrevTrunk->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3918
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3919
        iTrunk = get4byte(&pPage1->aData[32]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3920
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3921
      rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3922
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3923
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3924
        goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3925
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3926
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3927
      k = get4byte(&pTrunk->aData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3928
      if( k==0 && !searchList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3929
        /* The trunk has no leaves and the list is not being searched. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3930
        ** So extract the trunk page itself and use it as the newly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3931
        ** allocated page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3932
        assert( pPrevTrunk==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3933
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3934
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3935
          goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3936
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3937
        *pPgno = iTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3938
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3939
        *ppPage = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3940
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3941
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3942
      }else if( k>pBt->usableSize/4 - 8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3943
        /* Value of k is out of range.  Database corruption */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3944
        rc = SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3945
        goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3946
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3947
      }else if( searchList && nearby==iTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3948
        /* The list is being searched and this trunk page is the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3949
        ** to allocate, regardless of whether it has leaves.
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
        assert( *pPgno==iTrunk );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3952
        *ppPage = pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3953
        searchList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3954
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3955
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3956
          goto end_allocate_page;
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
        if( k==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3959
          if( !pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3960
            memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3961
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3962
            memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3963
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3964
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3965
          /* The trunk page is required by the caller but it contains 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3966
          ** pointers to free-list leaves. The first leaf becomes a trunk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3967
          ** page in this case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3968
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3969
          MemPage *pNewTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3970
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3971
          rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3972
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3973
            goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3974
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3975
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3976
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3977
            releasePage(pNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3978
            goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3979
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3980
          memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3981
          put4byte(&pNewTrunk->aData[4], k-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3982
          memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3983
          releasePage(pNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3984
          if( !pPrevTrunk ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3985
            put4byte(&pPage1->aData[32], iNewTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3986
          }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3987
            rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3988
            if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3989
              goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3990
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3991
            put4byte(&pPrevTrunk->aData[0], iNewTrunk);
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
        pTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3995
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3996
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3997
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3998
        /* Extract a leaf from the trunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  3999
        int closest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4000
        Pgno iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4001
        unsigned char *aData = pTrunk->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4002
        rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4003
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4004
          goto end_allocate_page;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4005
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4006
        if( nearby>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4007
          int i, dist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4008
          closest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4009
          dist = get4byte(&aData[8]) - nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4010
          if( dist<0 ) dist = -dist;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4011
          for(i=1; i<k; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4012
            int d2 = get4byte(&aData[8+i*4]) - nearby;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4013
            if( d2<0 ) d2 = -d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4014
            if( d2<dist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4015
              closest = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4016
              dist = d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4017
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4018
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4019
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4020
          closest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4021
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4023
        iPage = get4byte(&aData[8+closest*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4024
        if( !searchList || iPage==nearby ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4025
          *pPgno = iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4026
          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4027
            /* Free page off the end of the file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4028
            return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4029
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4030
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4031
                 ": %d more free pages\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4032
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4033
          if( closest<k-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4034
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4035
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4036
          put4byte(&aData[4], k-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4037
          rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4038
          if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4039
            sqlite3PagerDontRollback((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4040
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4041
            if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4042
              releasePage(*ppPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4043
            }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4044
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4045
          searchList = 0;
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
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4048
      releasePage(pPrevTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4049
      pPrevTrunk = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4050
    }while( searchList );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4051
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4052
    /* There are no pages on the freelist, so create a new page at the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4053
    ** end of the file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4054
    *pPgno = sqlite3PagerPagecount(pBt->pPager) + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4055
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4056
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4057
    if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4058
      /* An incr-vacuum has already run within this transaction. So the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4059
      ** page to allocate is not from the physical end of the file, but
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4060
      ** at pBt->nTrunc. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4061
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4062
      *pPgno = pBt->nTrunc+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4063
      if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4064
        (*pPgno)++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4065
      }
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
    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4068
      /* If *pPgno refers to a pointer-map page, allocate two new pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4069
      ** at the end of the file instead of one. The first allocated page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4070
      ** becomes a new pointer-map page, the second is used by the caller.
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
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4073
      assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4074
      (*pPgno)++;
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
    if( pBt->nTrunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4077
      pBt->nTrunc = *pPgno;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4080
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4081
    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4082
    rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4083
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4084
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4085
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4086
      releasePage(*ppPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4087
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4088
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4089
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4090
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4091
  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4092
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4093
end_allocate_page:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4094
  releasePage(pTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4095
  releasePage(pPrevTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4096
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4097
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4098
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4099
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4100
** Add a page of the database file to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4101
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4102
** sqlite3PagerUnref() is NOT called for pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4103
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4104
static int freePage(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4105
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4106
  MemPage *pPage1 = pBt->pPage1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4107
  int rc, n, k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4108
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4109
  /* Prepare the page for freeing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4110
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4111
  assert( pPage->pgno>1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4112
  pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4113
  releasePage(pPage->pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4114
  pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4115
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4116
  /* Increment the free page count on pPage1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4117
  rc = sqlite3PagerWrite(pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4118
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4119
  n = get4byte(&pPage1->aData[36]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4120
  put4byte(&pPage1->aData[36], n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4121
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4122
#ifdef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4123
  /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4124
  ** always fully overwrite deleted information with zeros.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4125
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4126
  rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4127
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4128
  memset(pPage->aData, 0, pPage->pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4129
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4130
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4131
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4132
  /* If the database supports auto-vacuum, write an entry in the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4133
  ** to indicate that the page is free.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4134
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4135
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4136
    rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4137
    if( rc ) 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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4140
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4141
  if( n==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4142
    /* This is the first free page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4143
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4144
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4145
    memset(pPage->aData, 0, 8);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4146
    put4byte(&pPage1->aData[32], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4147
    TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
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
    /* Other free pages already exist.  Retrive the first trunk page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4150
    ** of the freelist and find out how many leaves it has. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4151
    MemPage *pTrunk;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4152
    rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4153
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4154
    k = get4byte(&pTrunk->aData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4155
    if( k>=pBt->usableSize/4 - 8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4156
      /* The trunk is full.  Turn the page being freed into a new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4157
      ** trunk page with no leaves. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4158
      rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4159
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4160
        put4byte(pPage->aData, pTrunk->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4161
        put4byte(&pPage->aData[4], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4162
        put4byte(&pPage1->aData[32], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4163
        TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4164
                pPage->pgno, pTrunk->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4165
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4166
    }else if( k<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4167
      rc = SQLITE_CORRUPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4168
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4169
      /* Add the newly freed page as a leaf on the current trunk */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4170
      rc = sqlite3PagerWrite(pTrunk->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4171
      if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4172
        put4byte(&pTrunk->aData[4], k+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4173
        put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4174
#ifndef SQLITE_SECURE_DELETE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4175
        sqlite3PagerDontWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4176
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4177
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4178
      TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4179
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4180
    releasePage(pTrunk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4181
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4182
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4183
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4186
** Free any overflow pages associated with the given Cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4187
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4188
static int clearCell(MemPage *pPage, unsigned char *pCell){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4189
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4190
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4191
  Pgno ovflPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4192
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4193
  int nOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4194
  int ovflPageSize;
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
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4197
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4198
  if( info.iOverflow==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4199
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4200
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4201
  ovflPgno = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4202
  ovflPageSize = pBt->usableSize - 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4203
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4204
  assert( ovflPgno==0 || nOvfl>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4205
  while( nOvfl-- ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4206
    MemPage *pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4207
    if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4208
      return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4209
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4210
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4211
    rc = getOverflowPage(pBt, ovflPgno, &pOvfl, (nOvfl==0)?0:&ovflPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4212
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4213
    rc = freePage(pOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4214
    sqlite3PagerUnref(pOvfl->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4215
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4216
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4217
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4218
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4219
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
** Create the byte sequence used to represent a cell on page pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4222
** and write that byte sequence into pCell[].  Overflow pages are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4223
** allocated and filled in as necessary.  The calling procedure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4224
** is responsible for making sure sufficient space has been allocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4225
** for pCell[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4226
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4227
** Note that pCell does not necessary need to point to the pPage->aData
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4228
** area.  pCell might point to some temporary storage.  The cell will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4229
** be constructed in this temporary area then copied into pPage->aData
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4230
** later.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4231
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4232
static int fillInCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4233
  MemPage *pPage,                /* The page that contains the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4234
  unsigned char *pCell,          /* Complete text of the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4235
  const void *pKey, i64 nKey,    /* The key */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4236
  const void *pData,int nData,   /* The data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4237
  int nZero,                     /* Extra zero bytes to append to pData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4238
  int *pnSize                    /* Write cell size here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4239
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4240
  int nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4241
  const u8 *pSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4242
  int nSrc, n, rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4243
  int spaceLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4244
  MemPage *pOvfl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4245
  MemPage *pToRelease = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4246
  unsigned char *pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4247
  unsigned char *pPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4248
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4249
  Pgno pgnoOvfl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4250
  int nHeader;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4251
  CellInfo info;
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( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4254
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4255
  /* Fill in the header. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4256
  nHeader = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4257
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4258
    nHeader += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4259
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4260
  if( pPage->hasData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4261
    nHeader += putVarint(&pCell[nHeader], nData+nZero);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4262
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4263
    nData = nZero = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4265
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4266
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4267
  assert( info.nHeader==nHeader );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4268
  assert( info.nKey==nKey );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4269
  assert( info.nData==nData+nZero );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4270
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4271
  /* Fill in the payload */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4272
  nPayload = nData + nZero;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4273
  if( pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4274
    pSrc = (const u8*)pData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4275
    nSrc = nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4276
    nData = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4277
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4278
    nPayload += nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4279
    pSrc = (const u8*)pKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4280
    nSrc = nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4281
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4282
  *pnSize = info.nSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4283
  spaceLeft = info.nLocal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4284
  pPayload = &pCell[nHeader];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4285
  pPrior = &pCell[info.iOverflow];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4286
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4287
  while( nPayload>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4288
    if( spaceLeft==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4289
      int isExact = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4290
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4291
      Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4292
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4293
        do{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4294
          pgnoOvfl++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4295
        } while( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4296
          PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4297
        );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4298
        if( pgnoOvfl>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4299
          /* isExact = 1; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4300
        }
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4303
      rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, isExact);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4304
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4305
      /* If the database supports auto-vacuum, and the second or subsequent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4306
      ** overflow page is being allocated, add an entry to the pointer-map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4307
      ** for that page now. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4308
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4309
      ** If this is the first overflow page, then write a partial entry 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4310
      ** to the pointer-map. If we write nothing to this pointer-map slot,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4311
      ** then the optimistic overflow chain processing in clearCell()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4312
      ** may misinterpret the uninitialised values and delete the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4313
      ** wrong pages from the database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4314
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4315
      if( pBt->autoVacuum && rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4316
        u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4317
        rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4318
        if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4319
          releasePage(pOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4320
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4321
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4322
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4323
      if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4324
        releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4325
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4326
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4327
      put4byte(pPrior, pgnoOvfl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4328
      releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4329
      pToRelease = pOvfl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4330
      pPrior = pOvfl->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4331
      put4byte(pPrior, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4332
      pPayload = &pOvfl->aData[4];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4333
      spaceLeft = pBt->usableSize - 4;
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
    n = nPayload;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4336
    if( n>spaceLeft ) n = spaceLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4337
    if( nSrc>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4338
      if( n>nSrc ) n = nSrc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4339
      assert( pSrc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4340
      memcpy(pPayload, pSrc, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4341
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4342
      memset(pPayload, 0, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4343
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4344
    nPayload -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4345
    pPayload += n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4346
    pSrc += n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4347
    nSrc -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4348
    spaceLeft -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4349
    if( nSrc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4350
      nSrc = nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4351
      pSrc = (u8*)pData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4352
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4353
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4354
  releasePage(pToRelease);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4355
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4356
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4357
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4358
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4359
** Change the MemPage.pParent pointer on the page whose number is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4360
** given in the second argument so that MemPage.pParent holds the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4361
** pointer in the third argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4362
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4363
static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4364
  MemPage *pThis;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4365
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4366
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4367
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4368
  assert( pNewParent!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4369
  if( pgno==0 ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4370
  assert( pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4371
  pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4372
  if( pDbPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4373
    pThis = (MemPage *)sqlite3PagerGetExtra(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4374
    if( pThis->isInit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4375
      assert( pThis->aData==sqlite3PagerGetData(pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4376
      if( pThis->pParent!=pNewParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4377
        if( pThis->pParent ) sqlite3PagerUnref(pThis->pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4378
        pThis->pParent = pNewParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4379
        sqlite3PagerRef(pNewParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4380
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4381
      pThis->idxParent = idx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4382
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4383
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4384
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4385
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4386
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4387
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4388
    return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4391
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4392
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4393
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4394
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4395
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
** Change the pParent pointer of all children of pPage to point back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4398
** to pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4399
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4400
** In other words, for every child of pPage, invoke reparentPage()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4401
** to make sure that each child knows that pPage is its parent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4402
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4403
** This routine gets called after you memcpy() one page into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4404
** another.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4405
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4406
static int reparentChildPages(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4407
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4408
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4409
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4410
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4411
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4412
  if( pPage->leaf ) return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4413
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4414
  for(i=0; i<pPage->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4415
    u8 *pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4416
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4417
      rc = reparentPage(pBt, get4byte(pCell), pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4418
      if( rc!=SQLITE_OK ) return rc;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4421
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4422
    rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4423
       pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4424
    pPage->idxShift = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4425
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4426
  return rc;
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
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
** Remove the i-th cell from pPage.  This routine effects pPage only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4431
** The cell content is not freed or deallocated.  It is assumed that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4432
** the cell content has been copied someplace else.  This routine just
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4433
** removes the reference to the cell from pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4434
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4435
** "sz" must be the number of bytes in the cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4436
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4437
static void dropCell(MemPage *pPage, int idx, int sz){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4438
  int i;          /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4439
  int pc;         /* Offset to cell content of cell being deleted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4440
  u8 *data;       /* pPage->aData */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4441
  u8 *ptr;        /* Used to move bytes around within data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4442
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4443
  assert( idx>=0 && idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4444
  assert( sz==cellSize(pPage, idx) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4445
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4446
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4447
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4448
  ptr = &data[pPage->cellOffset + 2*idx];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4449
  pc = get2byte(ptr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4450
  assert( pc>10 && pc+sz<=pPage->pBt->usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4451
  freeSpace(pPage, pc, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4452
  for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4453
    ptr[0] = ptr[2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4454
    ptr[1] = ptr[3];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4455
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4456
  pPage->nCell--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4457
  put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4458
  pPage->nFree += 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4459
  pPage->idxShift = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4460
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4461
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
** Insert a new cell on pPage at cell index "i".  pCell points to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4464
** content of the cell.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4465
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4466
** If the cell content will fit on the page, then put it there.  If it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4467
** will not fit, then make a copy of the cell content into pTemp if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4468
** pTemp is not null.  Regardless of pTemp, allocate a new entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4469
** in pPage->aOvfl[] and make it point to the cell content (either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4470
** in pTemp or the original pCell) and also record its index. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4471
** Allocating a new entry in pPage->aCell[] implies that 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4472
** pPage->nOverflow is incremented.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4473
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4474
** If nSkip is non-zero, then do not copy the first nSkip bytes of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4475
** cell. The caller will overwrite them after this function returns. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4476
** nSkip is non-zero, then pCell may not point to an invalid memory location 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4477
** (but pCell+nSkip is always valid).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4478
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4479
static int insertCell(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4480
  MemPage *pPage,   /* Page into which we are copying */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4481
  int i,            /* New cell becomes the i-th cell of the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4482
  u8 *pCell,        /* Content of the new cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4483
  int sz,           /* Bytes of content in pCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4484
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4485
  u8 nSkip          /* Do not write the first nSkip bytes of the cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4486
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4487
  int idx;          /* Where to write new cell content in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4488
  int j;            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4489
  int top;          /* First byte of content for any cell in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4490
  int end;          /* First byte past the last cell pointer in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4491
  int ins;          /* Index in data[] where new cell pointer is inserted */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4492
  int hdr;          /* Offset into data[] of the page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4493
  int cellOffset;   /* Address of first cell pointer in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4494
  u8 *data;         /* The content of the whole page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4495
  u8 *ptr;          /* Used for moving information around in data[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4496
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4497
  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4498
  assert( sz==cellSizePtr(pPage, pCell) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4499
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4500
  if( pPage->nOverflow || sz+2>pPage->nFree ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4501
    if( pTemp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4502
      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4503
      pCell = pTemp;
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
    j = pPage->nOverflow++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4506
    assert( j<sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4507
    pPage->aOvfl[j].pCell = pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4508
    pPage->aOvfl[j].idx = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4509
    pPage->nFree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4510
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4511
    int rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4512
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4513
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4514
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4515
    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4516
    data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4517
    hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4518
    top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4519
    cellOffset = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4520
    end = cellOffset + 2*pPage->nCell + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4521
    ins = cellOffset + 2*i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4522
    if( end > top - sz ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4523
      rc = defragmentPage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4524
      if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4525
      top = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4526
      assert( end + sz <= top );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4527
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4528
    idx = allocateSpace(pPage, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4529
    assert( idx>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4530
    assert( end <= get2byte(&data[hdr+5]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4531
    pPage->nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4532
    pPage->nFree -= 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4533
    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4534
    for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4535
      ptr[0] = ptr[-2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4536
      ptr[1] = ptr[-1];
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
    put2byte(&data[ins], idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4539
    put2byte(&data[hdr+3], pPage->nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4540
    pPage->idxShift = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4541
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4542
    if( pPage->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4543
      /* The cell may contain a pointer to an overflow page. If so, write
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4544
      ** the entry for the overflow page into the pointer map.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4545
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4546
      CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4547
      sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4548
      assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4549
      if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4550
        Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4551
        rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4552
        if( rc!=SQLITE_OK ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4553
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4554
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4555
#endif
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4558
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4559
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4560
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4561
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4562
** Add a list of cells to a page.  The page should be initially empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4563
** The cells are guaranteed to fit on the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4564
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4565
static void assemblePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4566
  MemPage *pPage,   /* The page to be assemblied */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4567
  int nCell,        /* The number of cells to add to this page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4568
  u8 **apCell,      /* Pointers to cell bodies */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4569
  int *aSize        /* Sizes of the cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4570
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4571
  int i;            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4572
  int totalSize;    /* Total size of all cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4573
  int hdr;          /* Index of page header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4574
  int cellptr;      /* Address of next cell pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4575
  int cellbody;     /* Address of next cell body */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4576
  u8 *data;         /* Data for the page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4577
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4578
  assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4579
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4580
  totalSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4581
  for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4582
    totalSize += aSize[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4583
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4584
  assert( totalSize+2*nCell<=pPage->nFree );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4585
  assert( pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4586
  cellptr = pPage->cellOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4587
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4588
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4589
  put2byte(&data[hdr+3], nCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4590
  if( nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4591
    cellbody = allocateSpace(pPage, totalSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4592
    assert( cellbody>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4593
    assert( pPage->nFree >= 2*nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4594
    pPage->nFree -= 2*nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4595
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4596
      put2byte(&data[cellptr], cellbody);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4597
      memcpy(&data[cellbody], apCell[i], aSize[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4598
      cellptr += 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4599
      cellbody += aSize[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4600
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4601
    assert( cellbody==pPage->pBt->usableSize );
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
  pPage->nCell = nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4604
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4605
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4606
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4607
** The following parameters determine how many adjacent pages get involved
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4608
** in a balancing operation.  NN is the number of neighbors on either side
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4609
** of the page that participate in the balancing operation.  NB is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4610
** total number of pages that participate, including the target page and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4611
** NN neighbors on either side.
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
** The minimum value of NN is 1 (of course).  Increasing NN above 1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4614
** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4615
** in exchange for a larger degradation in INSERT and UPDATE performance.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4616
** The value of NN appears to give the best results overall.
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
#define NN 1             /* Number of neighbors on either side of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4619
#define NB (NN*2+1)      /* Total pages involved in the balance */
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
/* Forward reference */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4622
static int balance(MemPage*, int);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4623
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4624
#ifndef SQLITE_OMIT_QUICKBALANCE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4625
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4626
** This version of balance() handles the common special case where
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4627
** a new entry is being inserted on the extreme right-end of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4628
** tree, in other words, when the new entry will become the largest
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4629
** entry in the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4630
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4631
** Instead of trying balance the 3 right-most leaf pages, just add
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4632
** a new page to the right-hand side and put the one new entry in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4633
** that page.  This leaves the right side of the tree somewhat
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4634
** unbalanced.  But odds are that we will be inserting new entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4635
** at the end soon afterwards so the nearly empty page will quickly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4636
** fill up.  On average.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4637
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4638
** pPage is the leaf page which is the right-most page in the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4639
** pParent is its parent.  pPage must have a single overflow entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4640
** which is also the right-most entry on the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4641
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4642
static int balance_quick(MemPage *pPage, MemPage *pParent){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4643
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4644
  MemPage *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4645
  Pgno pgnoNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4646
  u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4647
  int szCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4648
  CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4649
  BtShared *pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4650
  int parentIdx = pParent->nCell;   /* pParent new divider cell index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4651
  int parentSize;                   /* Size of new divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4652
  u8 parentCell[64];                /* Space for the new divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4653
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4654
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4656
  /* Allocate a new page. Insert the overflow cell from pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4657
  ** into it. Then remove the overflow cell from pPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4658
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4659
  rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4660
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4661
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4662
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4663
  pCell = pPage->aOvfl[0].pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4664
  szCell = cellSizePtr(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4665
  zeroPage(pNew, pPage->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4666
  assemblePage(pNew, 1, &pCell, &szCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4667
  pPage->nOverflow = 0;
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
  /* Set the parent of the newly allocated page to pParent. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4670
  pNew->pParent = pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4671
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4673
  /* pPage is currently the right-child of pParent. Change this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4674
  ** so that the right-child is the new page allocated above and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4675
  ** pPage is the next-to-right child. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4676
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4677
  assert( pPage->nCell>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4678
  pCell = findCell(pPage, pPage->nCell-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4679
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4680
  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4681
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4682
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4683
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4684
  assert( parentSize<64 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4685
  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4686
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4687
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4688
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4689
  put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4690
  put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4691
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4692
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4693
  /* If this is an auto-vacuum database, update the pointer map
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4694
  ** with entries for the new page, and any pointer from the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4695
  ** cell on the page to an overflow page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4696
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4697
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4698
    rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4699
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4700
      rc = ptrmapPutOvfl(pNew, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4701
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4702
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4703
      releasePage(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4704
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4705
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4706
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4707
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4708
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4709
  /* Release the reference to the new page and balance the parent page,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4710
  ** in case the divider cell inserted caused it to become overfull.
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
  releasePage(pNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4713
  return balance(pParent, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4714
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4715
#endif /* SQLITE_OMIT_QUICKBALANCE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4716
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4717
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4718
** This routine redistributes Cells on pPage and up to NN*2 siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4719
** of pPage so that all pages have about the same amount of free space.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4720
** Usually NN siblings on either side of pPage is used in the balancing,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4721
** though more siblings might come from one side if pPage is the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4722
** or last child of its parent.  If pPage has fewer than 2*NN siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4723
** (something which can only happen if pPage is the root page or a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4724
** child of root) then all available siblings participate in the balancing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4725
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4726
** The number of siblings of pPage might be increased or decreased by one or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4727
** two in an effort to keep pages nearly full but not over full. The root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4728
** is special and is allowed to be nearly empty. If pPage is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4729
** the root page, then the depth of the tree might be increased
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4730
** or decreased by one, as necessary, to keep the root page from being
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4731
** overfull or completely empty.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4732
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4733
** Note that when this routine is called, some of the Cells on pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4734
** might not actually be stored in pPage->aData[].  This can happen
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4735
** if the page is overfull.  Part of the job of this routine is to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4736
** make sure all Cells for pPage once again fit in pPage->aData[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4737
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4738
** In the course of balancing the siblings of pPage, the parent of pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4739
** might become overfull or underfull.  If that happens, then this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4740
** is called recursively on the parent.
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
** If this routine fails for any reason, it might leave the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4743
** in a corrupted state.  So if this routine fails, the database should
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4744
** be rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4745
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4746
static int balance_nonroot(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4747
  MemPage *pParent;            /* The parent of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4748
  BtShared *pBt;               /* The whole database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4749
  int nCell = 0;               /* Number of cells in apCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4750
  int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4751
  int nOld;                    /* Number of pages in apOld[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4752
  int nNew;                    /* Number of pages in apNew[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4753
  int nDiv;                    /* Number of cells in apDiv[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4754
  int i, j, k;                 /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4755
  int idx;                     /* Index of pPage in pParent->aCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4756
  int nxDiv;                   /* Next divider slot in pParent->aCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4757
  int rc;                      /* The return code */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4758
  int leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4759
  int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4760
  int usableSpace;             /* Bytes in pPage beyond the header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4761
  int pageFlags;               /* Value of pPage->aData[0] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4762
  int subtotal;                /* Subtotal of bytes in cells on one page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4763
  int iSpace = 0;              /* First unused byte of aSpace[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4764
  MemPage *apOld[NB];          /* pPage and up to two siblings */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4765
  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4766
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4767
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4768
  Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4769
  u8 *apDiv[NB];               /* Divider cells in pParent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4770
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4771
  int szNew[NB+2];             /* Combined size of cells place on i-th page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4772
  u8 **apCell = 0;             /* All cells begin balanced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4773
  int *szCell;                 /* Local size of all cells in apCell[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4774
  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4775
  u8 *aSpace;                  /* Space to hold copies of dividers cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4776
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4777
  u8 *aFrom = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4778
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4779
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4780
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4781
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4782
  /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4783
  ** Find the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4784
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4785
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4786
  assert( sqlite3PagerIswriteable(pPage->pDbPage) || pPage->nOverflow==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4787
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4788
  pParent = pPage->pParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4789
  assert( pParent );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4790
  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4791
    return rc;
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
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4794
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4795
#ifndef SQLITE_OMIT_QUICKBALANCE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4796
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4797
  ** A special case:  If a new entry has just been inserted into a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4798
  ** table (that is, a btree with integer keys and all data at the leaves)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4799
  ** and the new entry is the right-most entry in the tree (it has the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4800
  ** largest key) then use the special balance_quick() routine for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4801
  ** balancing.  balance_quick() is much faster and results in a tighter
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4802
  ** packing of data in the common case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4803
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4804
  if( pPage->leaf &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4805
      pPage->intKey &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4806
      pPage->leafData &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4807
      pPage->nOverflow==1 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4808
      pPage->aOvfl[0].idx==pPage->nCell &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4809
      pPage->pParent->pgno!=1 &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4810
      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4811
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4812
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4813
    ** TODO: Check the siblings to the left of pPage. It may be that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4814
    ** they are not full and no new page is required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4815
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4816
    return balance_quick(pPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4817
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4818
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4819
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4820
  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4821
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4822
  }
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
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4825
  ** Find the cell in the parent page whose left child points back
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4826
  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4827
  ** is the rightmost child of pParent then set idx to pParent->nCell 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4828
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4829
  if( pParent->idxShift ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4830
    Pgno pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4831
    pgno = pPage->pgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4832
    assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4833
    for(idx=0; idx<pParent->nCell; idx++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4834
      if( get4byte(findCell(pParent, idx))==pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4835
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4836
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4837
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4838
    assert( idx<pParent->nCell
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4839
             || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4840
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4841
    idx = pPage->idxParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4842
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4843
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
  ** Initialize variables so that it will be safe to jump
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4846
  ** directly to balance_cleanup at any moment.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4847
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4848
  nOld = nNew = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4849
  sqlite3PagerRef(pParent->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4850
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
  ** Find sibling pages to pPage and the cells in pParent that divide
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4853
  ** the siblings.  An attempt is made to find NN siblings on either
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4854
  ** side of pPage.  More siblings are taken from one side, however, if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4855
  ** pPage there are fewer than NN siblings on the other side.  If pParent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4856
  ** has NB or fewer children then all children of pParent are taken.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4857
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4858
  nxDiv = idx - NN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4859
  if( nxDiv + NB > pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4860
    nxDiv = pParent->nCell - NB + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4861
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4862
  if( nxDiv<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4863
    nxDiv = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4864
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4865
  nDiv = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4866
  for(i=0, k=nxDiv; i<NB; i++, k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4867
    if( k<pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4868
      apDiv[i] = findCell(pParent, k);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4869
      nDiv++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4870
      assert( !pParent->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4871
      pgnoOld[i] = get4byte(apDiv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4872
    }else if( k==pParent->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4873
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4874
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4875
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4876
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4877
    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4878
    if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4879
    apOld[i]->idxParent = k;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4880
    apCopy[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4881
    assert( i==nOld );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4882
    nOld++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4883
    nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4884
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4885
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4886
  /* Make nMaxCells a multiple of 2 in order to preserve 8-byte
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4887
  ** alignment */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4888
  nMaxCells = (nMaxCells + 1)&~1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4889
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
  ** Allocate space for memory structures
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
  apCell = (u8**)sqlite3_malloc( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4894
       nMaxCells*sizeof(u8*)                           /* apCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4895
     + nMaxCells*sizeof(int)                           /* szCell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4896
     + ROUND8(sizeof(MemPage))*NB                      /* aCopy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4897
     + pBt->pageSize*(5+NB)                            /* aSpace */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4898
     + (ISAUTOVACUUM ? nMaxCells : 0)                  /* aFrom */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4899
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4900
  if( apCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4901
    rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4902
    goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4903
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4904
  szCell = (int*)&apCell[nMaxCells];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4905
  aCopy[0] = (u8*)&szCell[nMaxCells];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4906
  assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4907
  for(i=1; i<NB; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4908
    aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4909
    assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
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
  aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4912
  assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4913
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4914
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4915
    aFrom = &aSpace[5*pBt->pageSize];
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4918
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4919
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4920
  ** Make copies of the content of pPage and its siblings into aOld[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4921
  ** The rest of this function will use data from the copies rather
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4922
  ** that the original pages since the original pages will be in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4923
  ** process of being overwritten.
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
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4926
    MemPage *p = apCopy[i] = (MemPage*)aCopy[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4927
    memcpy(p, apOld[i], sizeof(MemPage));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4928
    p->aData = (u8*)(void*)&p[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4929
    memcpy(p->aData, apOld[i]->aData, pBt->pageSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4930
  }
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
  ** Load pointers to all cells on sibling pages and the divider cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4934
  ** into the local apCell[] array.  Make copies of the divider cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4935
  ** into space obtained form aSpace[] and remove the the divider Cells
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4936
  ** from pParent.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4937
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4938
  ** If the siblings are on leaf pages, then the child pointers of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4939
  ** divider cells are stripped from the cells before they are copied
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4940
  ** into aSpace[].  In this way, all cells in apCell[] are without
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4941
  ** child pointers.  If siblings are not leaves, then all cell in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4942
  ** apCell[] include child pointers.  Either way, all cells in apCell[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4943
  ** are alike.
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
  ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4946
  **       leafData:  1 if pPage holds key+data and pParent holds only keys.
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
  nCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4949
  leafCorrection = pPage->leaf*4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4950
  leafData = pPage->leafData && pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4951
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4952
    MemPage *pOld = apCopy[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4953
    int limit = pOld->nCell+pOld->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4954
    for(j=0; j<limit; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4955
      assert( nCell<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4956
      apCell[nCell] = findOverflowCell(pOld, j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4957
      szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4958
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4959
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4960
        int a;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4961
        aFrom[nCell] = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4962
        for(a=0; a<pOld->nOverflow; a++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4963
          if( pOld->aOvfl[a].pCell==apCell[nCell] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4964
            aFrom[nCell] = 0xFF;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4965
            break;
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
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4968
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4969
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4970
      nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4971
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4972
    if( i<nOld-1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4973
      int sz = cellSizePtr(pParent, apDiv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4974
      if( leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4975
        /* With the LEAFDATA flag, pParent cells hold only INTKEYs that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4976
        ** are duplicates of keys on the child pages.  We need to remove
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4977
        ** the divider cells from pParent, but the dividers cells are not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4978
        ** added to apCell[] because they are duplicates of child cells.
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
        dropCell(pParent, nxDiv, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4981
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4982
        u8 *pTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4983
        assert( nCell<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4984
        szCell[nCell] = sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4985
        pTemp = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4986
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4987
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4988
        memcpy(pTemp, apDiv[i], sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4989
        apCell[nCell] = pTemp+leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4990
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4991
        if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4992
          aFrom[nCell] = 0xFF;
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4995
        dropCell(pParent, nxDiv, sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4996
        szCell[nCell] -= leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4997
        assert( get4byte(pTemp)==pgnoOld[i] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4998
        if( !pOld->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  4999
          assert( leafCorrection==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5000
          /* The right pointer of the child page pOld becomes the left
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5001
          ** pointer of the divider cell */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5002
          memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5003
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5004
          assert( leafCorrection==4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5005
          if( szCell[nCell]<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5006
            /* Do not allow any cells smaller than 4 bytes. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5007
            szCell[nCell] = 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5008
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5009
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5010
        nCell++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5011
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5012
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5013
  }
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
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5016
  ** Figure out the number of pages needed to hold all nCell cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5017
  ** Store this number in "k".  Also compute szNew[] which is the total
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5018
  ** size of all cells on the i-th page and cntNew[] which is the index
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5019
  ** in apCell[] of the cell that divides page i from page i+1.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5020
  ** cntNew[k] should equal nCell.
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
  ** Values computed by this block:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5023
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5024
  **           k: The total number of sibling pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5025
  **    szNew[i]: Spaced used on the i-th sibling page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5026
  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5027
  **              the right of the i-th sibling page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5028
  ** usableSpace: Number of bytes of space available on each sibling.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5029
  ** 
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
  usableSpace = pBt->usableSize - 12 + leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5032
  for(subtotal=k=i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5033
    assert( i<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5034
    subtotal += szCell[i] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5035
    if( subtotal > usableSpace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5036
      szNew[k] = subtotal - szCell[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5037
      cntNew[k] = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5038
      if( leafData ){ i--; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5039
      subtotal = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5040
      k++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5041
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5042
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5043
  szNew[k] = subtotal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5044
  cntNew[k] = nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5045
  k++;
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
  ** The packing computed by the previous block is biased toward the siblings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5049
  ** on the left side.  The left siblings are always nearly full, while the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5050
  ** right-most sibling might be nearly empty.  This block of code attempts
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5051
  ** to adjust the packing of siblings to get a better balance.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5052
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5053
  ** This adjustment is more than an optimization.  The packing above might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5054
  ** be so out of balance as to be illegal.  For example, the right-most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5055
  ** sibling might be completely empty.  This adjustment is not optional.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5056
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5057
  for(i=k-1; i>0; i--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5058
    int szRight = szNew[i];  /* Size of sibling on the right */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5059
    int szLeft = szNew[i-1]; /* Size of sibling on the left */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5060
    int r;              /* Index of right-most cell in left sibling */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5061
    int d;              /* Index of first cell to the left of right sibling */
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
    r = cntNew[i-1] - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5064
    d = r + 1 - leafData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5065
    assert( d<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5066
    assert( r<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5067
    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5068
      szRight += szCell[d] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5069
      szLeft -= szCell[r] + 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5070
      cntNew[i-1]--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5071
      r = cntNew[i-1] - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5072
      d = r + 1 - leafData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5073
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5074
    szNew[i] = szRight;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5075
    szNew[i-1] = szLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5076
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5077
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5078
  /* Either we found one or more cells (cntnew[0])>0) or we are the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5079
  ** a virtual root page.  A virtual root page is when the real root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5080
  ** page is page 1 and we are the only child of that page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5081
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5082
  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
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
  ** Allocate k new pages.  Reuse old pages where possible.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5086
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5087
  assert( pPage->pgno>1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5088
  pageFlags = pPage->aData[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5089
  for(i=0; i<k; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5090
    MemPage *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5091
    if( i<nOld ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5092
      pNew = apNew[i] = apOld[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5093
      pgnoNew[i] = pgnoOld[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5094
      apOld[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5095
      rc = sqlite3PagerWrite(pNew->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5096
      nNew++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5097
      if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5098
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5099
      assert( i>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5100
      rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5101
      if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5102
      apNew[i] = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5103
      nNew++;
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
    zeroPage(pNew, pageFlags);
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5108
  /* Free any old pages that were not reused as new pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5109
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5110
  while( i<nOld ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5111
    rc = freePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5112
    if( rc ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5113
    releasePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5114
    apOld[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5115
    i++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5116
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5118
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5119
  ** Put the new pages in accending order.  This helps to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5120
  ** keep entries in the disk file in order so that a scan
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5121
  ** of the table is a linear scan through the file.  That
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5122
  ** in turn helps the operating system to deliver pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5123
  ** from the disk more rapidly.
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
  ** An O(n^2) insertion sort algorithm is used, but since
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5126
  ** n is never more than NB (a small constant), that should
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5127
  ** not be a problem.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5128
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5129
  ** When NB==3, this one optimization makes the database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5130
  ** about 25% faster for large insertions and deletions.
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
  for(i=0; i<k-1; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5133
    int minV = pgnoNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5134
    int minI = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5135
    for(j=i+1; j<k; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5136
      if( pgnoNew[j]<(unsigned)minV ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5137
        minI = j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5138
        minV = pgnoNew[j];
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
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5141
    if( minI>i ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5142
      int t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5143
      MemPage *pT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5144
      t = pgnoNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5145
      pT = apNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5146
      pgnoNew[i] = pgnoNew[minI];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5147
      apNew[i] = apNew[minI];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5148
      pgnoNew[minI] = t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5149
      apNew[minI] = pT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5150
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5151
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5152
  TRACE(("BALANCE: old: %d %d %d  new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5153
    pgnoOld[0], 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5154
    nOld>=2 ? pgnoOld[1] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5155
    nOld>=3 ? pgnoOld[2] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5156
    pgnoNew[0], szNew[0],
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5157
    nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5158
    nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5159
    nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5160
    nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5161
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5162
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5163
  ** Evenly distribute the data in apCell[] across the new pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5164
  ** Insert divider cells into pParent as necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5165
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5166
  j = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5167
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5168
    /* Assemble the new sibling page. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5169
    MemPage *pNew = apNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5170
    assert( j<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5171
    assert( pNew->pgno==pgnoNew[i] );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5172
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5173
    assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5174
    assert( pNew->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5175
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5176
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5177
    /* If this is an auto-vacuum database, update the pointer map entries
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5178
    ** that point to the siblings that were rearranged. These can be: left
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5179
    ** children of cells, the right-child of the page, or overflow pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5180
    ** pointed to by cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5181
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5182
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5183
      for(k=j; k<cntNew[i]; k++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5184
        assert( k<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5185
        if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5186
          rc = ptrmapPutOvfl(pNew, k-j);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5187
          if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5188
            goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5189
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5190
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5191
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5192
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5193
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5194
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5195
    j = cntNew[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5196
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5197
    /* If the sibling page assembled above was not the right-most sibling,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5198
    ** insert a divider cell into the parent page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5199
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5200
    if( i<nNew-1 && j<nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5201
      u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5202
      u8 *pTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5203
      int sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5205
      assert( j<nMaxCells );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5206
      pCell = apCell[j];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5207
      sz = szCell[j] + leafCorrection;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5208
      if( !pNew->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5209
        memcpy(&pNew->aData[8], pCell, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5210
        pTemp = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5211
      }else if( leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5212
        /* If the tree is a leaf-data tree, and the siblings are leaves, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5213
        ** then there is no divider cell in apCell[]. Instead, the divider 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5214
        ** cell consists of the integer key for the right-most cell of 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5215
        ** the sibling-page assembled above only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5216
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5217
        CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5218
        j--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5219
        sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5220
        pCell = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5221
        fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5222
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5223
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5224
        pTemp = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5225
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5226
        pCell -= 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5227
        pTemp = &aSpace[iSpace];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5228
        iSpace += sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5229
        assert( iSpace<=pBt->pageSize*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5230
        /* Obscure case for non-leaf-data trees: If the cell at pCell was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5231
        ** previously stored on a leaf node, and its reported size was 4
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5232
        ** bytes, then it may actually be smaller than this 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5233
        ** (see sqlite3BtreeParseCellPtr(), 4 bytes is the minimum size of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5234
        ** any cell). But it is important to pass the correct size to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5235
        ** insertCell(), so reparse the cell now.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5236
        **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5237
        ** Note that this can never happen in an SQLite data file, as all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5238
        ** cells are at least 4 bytes. It only happens in b-trees used
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5239
        ** to evaluate "IN (SELECT ...)" and similar clauses.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5240
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5241
        if( szCell[j]==4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5242
          assert(leafCorrection==4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5243
          sz = cellSizePtr(pParent, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5244
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5245
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5246
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5247
      if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5248
      put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5249
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5250
      /* If this is an auto-vacuum database, and not a leaf-data tree,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5251
      ** then update the pointer map with an entry for the overflow page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5252
      ** that the cell just inserted points to (if any).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5253
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5254
      if( pBt->autoVacuum && !leafData ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5255
        rc = ptrmapPutOvfl(pParent, nxDiv);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5256
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5257
          goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5258
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5259
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5260
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5261
      j++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5262
      nxDiv++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5263
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5265
  assert( j==nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5266
  assert( nOld>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5267
  assert( nNew>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5268
  if( (pageFlags & PTF_LEAF)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5269
    memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5270
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5271
  if( nxDiv==pParent->nCell+pParent->nOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5272
    /* Right-most sibling is the right-most child of pParent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5273
    put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5274
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5275
    /* Right-most sibling is the left child of the first entry in pParent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5276
    ** past the right-most divider entry */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5277
    put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5278
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5279
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5280
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5281
  ** Reparent children of all cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5282
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5283
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5284
    rc = reparentChildPages(apNew[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5285
    if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5286
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5287
  rc = reparentChildPages(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5288
  if( rc!=SQLITE_OK ) goto balance_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5289
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5290
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5291
  ** Balance the parent page.  Note that the current page (pPage) might
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5292
  ** have been added to the freelist so it might no longer be initialized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5293
  ** But the parent page will always be initialized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5294
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5295
  assert( pParent->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5296
  rc = balance(pParent, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5297
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5298
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5299
  ** Cleanup before returning.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5300
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5301
balance_cleanup:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5302
  sqlite3_free(apCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5303
  for(i=0; i<nOld; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5304
    releasePage(apOld[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5305
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5306
  for(i=0; i<nNew; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5307
    releasePage(apNew[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5308
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5309
  releasePage(pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5310
  TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5311
          pPage->pgno, nOld, nNew, nCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5312
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5313
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5315
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5316
** This routine is called for the root page of a btree when the root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5317
** page contains no cells.  This is an opportunity to make the tree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5318
** shallower by one level.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5319
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5320
static int balance_shallower(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5321
  MemPage *pChild;             /* The only child page of pPage */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5322
  Pgno pgnoChild;              /* Page number for pChild */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5323
  int rc = SQLITE_OK;          /* Return code from subprocedures */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5324
  BtShared *pBt;                  /* The main BTree structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5325
  int mxCellPerPage;           /* Maximum number of cells per page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5326
  u8 **apCell;                 /* All cells from pages being balanced */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5327
  int *szCell;                 /* Local size of all cells */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5328
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5329
  assert( pPage->pParent==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5330
  assert( pPage->nCell==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5331
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5332
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5333
  mxCellPerPage = MX_CELL(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5334
  apCell = (u8**)sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5335
  if( apCell==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5336
  szCell = (int*)&apCell[mxCellPerPage];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5337
  if( pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5338
    /* The table is completely empty */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5339
    TRACE(("BALANCE: empty table %d\n", pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5340
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5341
    /* The root page is empty but has one child.  Transfer the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5342
    ** information from that one child into the root page if it 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5343
    ** will fit.  This reduces the depth of the tree by one.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5344
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5345
    ** If the root page is page 1, it has less space available than
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5346
    ** its child (due to the 100 byte header that occurs at the beginning
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5347
    ** of the database fle), so it might not be able to hold all of the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5348
    ** information currently contained in the child.  If this is the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5349
    ** case, then do not do the transfer.  Leave page 1 empty except
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5350
    ** for the right-pointer to the child page.  The child page becomes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5351
    ** the virtual root of the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5352
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5353
    pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5354
    assert( pgnoChild>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5355
    assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5356
    rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5357
    if( rc ) goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5358
    if( pPage->pgno==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5359
      rc = sqlite3BtreeInitPage(pChild, pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5360
      if( rc ) goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5361
      assert( pChild->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5362
      if( pChild->nFree>=100 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5363
        /* The child information will fit on the root page, so do the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5364
        ** copy */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5365
        int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5366
        zeroPage(pPage, pChild->aData[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5367
        for(i=0; i<pChild->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5368
          apCell[i] = findCell(pChild,i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5369
          szCell[i] = cellSizePtr(pChild, apCell[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5370
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5371
        assemblePage(pPage, pChild->nCell, apCell, szCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5372
        /* Copy the right-pointer of the child to the parent. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5373
        put4byte(&pPage->aData[pPage->hdrOffset+8], 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5374
            get4byte(&pChild->aData[pChild->hdrOffset+8]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5375
        freePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5376
        TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5377
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5378
        /* The child has more information that will fit on the root.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5379
        ** The tree is already balanced.  Do nothing. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5380
        TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5381
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5382
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5383
      memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5384
      pPage->isInit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5385
      pPage->pParent = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5386
      rc = sqlite3BtreeInitPage(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5387
      assert( rc==SQLITE_OK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5388
      freePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5389
      TRACE(("BALANCE: transfer child %d into root %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5390
              pChild->pgno, pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5391
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5392
    rc = reparentChildPages(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5393
    assert( pPage->nOverflow==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5394
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5395
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5396
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5397
      for(i=0; i<pPage->nCell; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5398
        rc = ptrmapPutOvfl(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5399
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5400
          goto end_shallow_balance;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5401
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5402
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5403
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5404
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5405
    releasePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5406
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5407
end_shallow_balance:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5408
  sqlite3_free(apCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5409
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5410
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5411
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5412
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5413
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5414
** The root page is overfull
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5415
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5416
** When this happens, Create a new child page and copy the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5417
** contents of the root into the child.  Then make the root
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5418
** page an empty page with rightChild pointing to the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5419
** child.   Finally, call balance_internal() on the new child
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5420
** to cause it to split.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5421
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5422
static int balance_deeper(MemPage *pPage){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5423
  int rc;             /* Return value from subprocedures */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5424
  MemPage *pChild;    /* Pointer to a new child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5425
  Pgno pgnoChild;     /* Page number of the new child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5426
  BtShared *pBt;         /* The BTree */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5427
  int usableSize;     /* Total usable size of a page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5428
  u8 *data;           /* Content of the parent page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5429
  u8 *cdata;          /* Content of the child page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5430
  int hdr;            /* Offset to page header in parent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5431
  int brk;            /* Offset to content of first cell in parent */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5432
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5433
  assert( pPage->pParent==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5434
  assert( pPage->nOverflow>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5435
  pBt = pPage->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5436
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5437
  rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5438
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5439
  assert( sqlite3PagerIswriteable(pChild->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5440
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5441
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5442
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5443
  brk = get2byte(&data[hdr+5]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5444
  cdata = pChild->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5445
  memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5446
  memcpy(&cdata[brk], &data[brk], usableSize-brk);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5447
  assert( pChild->isInit==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5448
  rc = sqlite3BtreeInitPage(pChild, pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5449
  if( rc ) goto balancedeeper_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5450
  memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5451
  pChild->nOverflow = pPage->nOverflow;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5452
  if( pChild->nOverflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5453
    pChild->nFree = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5454
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5455
  assert( pChild->nCell==pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5456
  zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5457
  put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5458
  TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5459
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5460
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5461
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5462
    rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5463
    if( rc ) goto balancedeeper_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5464
    for(i=0; i<pChild->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5465
      rc = ptrmapPutOvfl(pChild, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5466
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5467
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5468
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5469
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5470
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5471
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5472
  rc = balance_nonroot(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5473
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5474
balancedeeper_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5475
  releasePage(pChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5476
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5477
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5478
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5479
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5480
** Decide if the page pPage needs to be balanced.  If balancing is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5481
** required, call the appropriate balancing routine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5482
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5483
static int balance(MemPage *pPage, int insert){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5484
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5485
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5486
  if( pPage->pParent==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5487
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5488
    if( rc==SQLITE_OK && pPage->nOverflow>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5489
      rc = balance_deeper(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5490
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5491
    if( rc==SQLITE_OK && pPage->nCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5492
      rc = balance_shallower(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5493
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5494
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5495
    if( pPage->nOverflow>0 || 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5496
        (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5497
      rc = balance_nonroot(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5498
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5499
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5500
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5501
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5502
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5503
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5504
** This routine checks all cursors that point to table pgnoRoot.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5505
** If any of those cursors were opened with wrFlag==0 in a different
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5506
** database connection (a database connection that shares the pager
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5507
** cache with the current connection) and that other connection 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5508
** is not in the ReadUncommmitted state, then this routine returns 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5509
** SQLITE_LOCKED.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5510
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5511
** In addition to checking for read-locks (where a read-lock 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5512
** means a cursor opened with wrFlag==0) this routine also moves
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5513
** all write cursors so that they are pointing to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5514
** first Cell on the root page.  This is necessary because an insert 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5515
** or delete might change the number of cells on a page or delete
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5516
** a page entirely and we do not want to leave any cursors 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5517
** pointing to non-existant pages or cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5518
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5519
static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5520
  BtCursor *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5521
  BtShared *pBt = pBtree->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5522
  sqlite3 *db = pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5523
  assert( sqlite3BtreeHoldsMutex(pBtree) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5524
  for(p=pBt->pCursor; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5525
    if( p==pExclude ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5526
    if( p->eState!=CURSOR_VALID ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5527
    if( p->pgnoRoot!=pgnoRoot ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5528
    if( p->wrFlag==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5529
      sqlite3 *dbOther = p->pBtree->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5530
      if( dbOther==0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5531
         (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5532
        return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5533
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5534
    }else if( p->pPage->pgno!=p->pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5535
      moveToRoot(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5536
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5537
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5538
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5539
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5540
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5541
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5542
** Insert a new record into the BTree.  The key is given by (pKey,nKey)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5543
** and the data is given by (pData,nData).  The cursor is used only to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5544
** define what table the record should be inserted into.  The cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5545
** is left pointing at a random location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5546
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5547
** For an INTKEY table, only the nKey value of the key is used.  pKey is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5548
** ignored.  For a ZERODATA table, the pData and nData are both ignored.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5549
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5550
int sqlite3BtreeInsert(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5551
  BtCursor *pCur,                /* Insert data into the table of this cursor */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5552
  const void *pKey, i64 nKey,    /* The key of the new record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5553
  const void *pData, int nData,  /* The data of the new record */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5554
  int nZero,                     /* Number of extra 0 bytes to append to data */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5555
  int appendBias                 /* True if this is likely an append */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5556
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5557
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5558
  int loc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5559
  int szNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5560
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5561
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5562
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5563
  unsigned char *oldCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5564
  unsigned char *newCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5565
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5566
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5567
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5568
    /* Must start a transaction before doing an insert */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5569
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5570
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5571
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5572
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5573
  if( !pCur->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5574
    return SQLITE_PERM;   /* Cursor not open for writing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5575
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5576
  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5577
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5578
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5579
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5580
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5581
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5583
  /* Save the positions of any other cursors open on this table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5584
  clearCursorPosition(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5585
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5586
    SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5587
    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5588
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5589
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5590
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5591
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5592
  pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5593
  assert( pPage->intKey || nKey>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5594
  assert( pPage->leaf || !pPage->leafData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5595
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5596
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5597
          loc==0 ? "overwrite" : "new entry"));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5598
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5599
  newCell = (unsigned char*)sqlite3_malloc( MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5600
  if( newCell==0 ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5601
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5602
  if( rc ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5603
  assert( szNew==cellSizePtr(pPage, newCell) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5604
  assert( szNew<=MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5605
  if( loc==0 && CURSOR_VALID==pCur->eState ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5606
    int szOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5607
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5608
    rc = sqlite3PagerWrite(pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5609
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5610
      goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5611
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5612
    oldCell = findCell(pPage, pCur->idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5613
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5614
      memcpy(newCell, oldCell, 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5615
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5616
    szOld = cellSizePtr(pPage, oldCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5617
    rc = clearCell(pPage, oldCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5618
    if( rc ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5619
    dropCell(pPage, pCur->idx, szOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5620
  }else if( loc<0 && pPage->nCell>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5621
    assert( pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5622
    pCur->idx++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5623
    pCur->info.nSize = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5624
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5625
    assert( pPage->leaf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5626
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5627
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5628
  if( rc!=SQLITE_OK ) goto end_insert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5629
  rc = balance(pPage, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5630
  /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5631
  /* fflush(stdout); */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5632
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5633
    moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5634
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5635
end_insert:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5636
  sqlite3_free(newCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5637
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5638
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5639
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5640
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5641
** Delete the entry that the cursor is pointing to.  The cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5642
** is left pointing at a random location.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5643
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5644
int sqlite3BtreeDelete(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5645
  MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5646
  unsigned char *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5647
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5648
  Pgno pgnoChild = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5649
  Btree *p = pCur->pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5650
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5651
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5652
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5653
  assert( pPage->isInit );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5654
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5655
    /* Must start a transaction before doing a delete */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5656
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5657
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5658
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5659
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5660
  if( pCur->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5661
    return pCur->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5662
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5663
  if( pCur->idx >= pPage->nCell ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5664
    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5665
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5666
  if( !pCur->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5667
    return SQLITE_PERM;   /* Did not open this cursor for writing */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5668
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5669
  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5670
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5671
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5672
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5673
  /* Restore the current cursor position (a no-op if the cursor is not in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5674
  ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5675
  ** open on the same table. Then call sqlite3PagerWrite() on the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5676
  ** that the entry will be deleted from.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5677
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5678
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5679
    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5680
    (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5681
    (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5682
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5683
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5684
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5685
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5686
  /* Locate the cell within its page and leave pCell pointing to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5687
  ** data. The clearCell() call frees any overflow pages associated with the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5688
  ** cell. The cell itself is still intact.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5689
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5690
  pCell = findCell(pPage, pCur->idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5691
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5692
    pgnoChild = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5693
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5694
  rc = clearCell(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5695
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5696
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5697
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5698
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5699
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5700
    /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5701
    ** The entry we are about to delete is not a leaf so if we do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5702
    ** do something we will leave a hole on an internal page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5703
    ** We have to fill the hole by moving in a cell from a leaf.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5704
    ** next Cell after the one to be deleted is guaranteed to exist and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5705
    ** to be a leaf so we can use it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5706
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5707
    BtCursor leafCur;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5708
    unsigned char *pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5709
    int szNext;  /* The compiler warning is wrong: szNext is always 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5710
                 ** initialized before use.  Adding an extra initialization
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5711
                 ** to silence the compiler slows down the code. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5712
    int notUsed;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5713
    unsigned char *tempCell = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5714
    assert( !pPage->leafData );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5715
    sqlite3BtreeGetTempCursor(pCur, &leafCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5716
    rc = sqlite3BtreeNext(&leafCur, &notUsed);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5717
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5718
      rc = sqlite3PagerWrite(leafCur.pPage->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5719
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5720
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5721
      TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5722
         pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5723
      dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5724
      pNext = findCell(leafCur.pPage, leafCur.idx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5725
      szNext = cellSizePtr(leafCur.pPage, pNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5726
      assert( MX_CELL_SIZE(pBt)>=szNext+4 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5727
      tempCell = (unsigned char*)sqlite3_malloc( MX_CELL_SIZE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5728
      if( tempCell==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5729
        rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5730
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5731
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5732
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5733
      rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5734
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5735
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5736
      put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5737
      rc = balance(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5738
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5739
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5740
      dropCell(leafCur.pPage, leafCur.idx, szNext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5741
      rc = balance(leafCur.pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5742
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5743
    sqlite3_free(tempCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5744
    sqlite3BtreeReleaseTempCursor(&leafCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5745
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5746
    TRACE(("DELETE: table=%d delete from leaf %d\n",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5747
       pCur->pgnoRoot, pPage->pgno));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5748
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5749
    rc = balance(pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5750
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5751
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5752
    moveToRoot(pCur);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5753
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5754
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5755
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5756
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5757
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5758
** Create a new BTree table.  Write into *piTable the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5759
** number for the root page of the new table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5760
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5761
** The type of type is determined by the flags parameter.  Only the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5762
** following values of flags are currently in use.  Other values for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5763
** flags might not work:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5764
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5765
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5766
**     BTREE_ZERODATA                  Used for SQL indices
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5767
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5768
static int btreeCreateTable(Btree *p, int *piTable, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5769
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5770
  MemPage *pRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5771
  Pgno pgnoRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5772
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5773
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5774
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5775
  if( pBt->inTransaction!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5776
    /* Must start a transaction first */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5777
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5778
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5779
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5780
  assert( !pBt->readOnly );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5781
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5782
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5783
  rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5784
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5785
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5786
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5787
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5788
  if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5789
    Pgno pgnoMove;      /* Move a page here to make room for the root-page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5790
    MemPage *pPageMove; /* The page to move to. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5791
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5792
    /* Creating a new table may probably require moving an existing database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5793
    ** to make room for the new tables root page. In case this page turns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5794
    ** out to be an overflow page, delete all overflow page-map caches
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5795
    ** held by open cursors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5796
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5797
    invalidateAllOverflowCache(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5798
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5799
    /* Read the value of meta[3] from the database to determine where the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5800
    ** root page of the new table should go. meta[3] is the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5801
    ** created so far, so the new root-page is (meta[3]+1).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5802
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5803
    rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5804
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5805
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5806
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5807
    pgnoRoot++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5808
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5809
    /* The new root-page may not be allocated on a pointer-map page, or the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5810
    ** PENDING_BYTE page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5811
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5812
    if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5813
        pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5814
      pgnoRoot++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5815
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5816
    assert( pgnoRoot>=3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5817
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5818
    /* Allocate a page. The page that currently resides at pgnoRoot will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5819
    ** be moved to the allocated page (unless the allocated page happens
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5820
    ** to reside at pgnoRoot).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5821
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5822
    rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5823
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5824
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5825
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5826
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5827
    if( pgnoMove!=pgnoRoot ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5828
      /* pgnoRoot is the page that will be used for the root-page of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5829
      ** the new table (assuming an error did not occur). But we were
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5830
      ** allocated pgnoMove. If required (i.e. if it was not allocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5831
      ** by extending the file), the current page at position pgnoMove
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5832
      ** is already journaled.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5833
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5834
      u8 eType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5835
      Pgno iPtrPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5836
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5837
      releasePage(pPageMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5838
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5839
      /* Move the page currently at pgnoRoot to pgnoMove. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5840
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5841
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5842
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5843
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5844
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5845
      if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5846
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5847
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5848
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5849
      assert( eType!=PTRMAP_ROOTPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5850
      assert( eType!=PTRMAP_FREEPAGE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5851
      rc = sqlite3PagerWrite(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5852
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5853
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5854
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5855
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5856
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5857
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5859
      /* Obtain the page at pgnoRoot */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5860
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5861
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5862
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5863
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5864
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5865
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5866
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5867
      rc = sqlite3PagerWrite(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5868
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5869
        releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5870
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5871
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5872
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5873
      pRoot = pPageMove;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5874
    } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5875
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5876
    /* Update the pointer-map and meta-data with the new root-page number. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5877
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5878
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5879
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5880
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5881
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5882
    rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5883
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5884
      releasePage(pRoot);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5885
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5886
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5887
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5888
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5889
    rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5890
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5891
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5892
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5893
  assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5894
  zeroPage(pRoot, flags | PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5895
  sqlite3PagerUnref(pRoot->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5896
  *piTable = (int)pgnoRoot;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5897
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5898
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5899
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5900
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5901
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5902
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5903
  rc = btreeCreateTable(p, piTable, flags);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5904
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5905
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5906
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5907
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5908
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5909
** Erase the given database page and all its children.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5910
** the page to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5911
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5912
static int clearDatabasePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5913
  BtShared *pBt,           /* The BTree that contains the table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5914
  Pgno pgno,            /* Page number to clear */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5915
  MemPage *pParent,     /* Parent page.  NULL for the root */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5916
  int freePageFlag      /* Deallocate page if true */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5917
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5918
  MemPage *pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5919
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5920
  unsigned char *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5921
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5922
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5923
  assert( sqlite3_mutex_held(pBt->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5924
  if( pgno>sqlite3PagerPagecount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5925
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5926
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5927
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5928
  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5929
  if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5930
  for(i=0; i<pPage->nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5931
    pCell = findCell(pPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5932
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5933
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5934
      if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5935
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5936
    rc = clearCell(pPage, pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5937
    if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5938
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5939
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5940
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5941
    if( rc ) goto cleardatabasepage_out;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5942
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5943
  if( freePageFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5944
    rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5945
  }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5946
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5947
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5948
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5949
cleardatabasepage_out:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5950
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5951
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5952
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5953
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5954
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5955
** Delete all information from a single table in the database.  iTable is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5956
** the page number of the root of the table.  After this routine returns,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5957
** the root page is empty, but still exists.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5958
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5959
** This routine will fail with SQLITE_LOCKED if there are any open
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5960
** read cursors on the table.  Open write cursors are moved to the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5961
** root of the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5962
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5963
int sqlite3BtreeClearTable(Btree *p, int iTable){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5964
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5965
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5966
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5967
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5968
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5969
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5970
  }else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5971
    /* nothing to do */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5972
  }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5973
    /* nothing to do */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5974
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5975
    rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5976
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5977
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5978
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5979
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5980
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5981
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5982
** Erase all information in a table and add the root of the table to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5983
** the freelist.  Except, the root of the principle table (the one on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5984
** page 1) is never added to the freelist.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5985
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5986
** This routine will fail with SQLITE_LOCKED if there are any open
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5987
** cursors on the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5988
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5989
** If AUTOVACUUM is enabled and the page at iTable is not the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5990
** root page in the database file, then the last root page 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5991
** in the database file is moved into the slot formerly occupied by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5992
** iTable and that last slot formerly occupied by the last root page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5993
** is added to the freelist instead of iTable.  In this say, all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5994
** root pages are kept at the beginning of the database file, which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5995
** is necessary for AUTOVACUUM to work right.  *piMoved is set to the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5996
** page number that used to be the last root page in the file before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5997
** the move.  If no page gets moved, *piMoved is set to 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5998
** The last root page is recorded in meta[3] and the value of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  5999
** meta[3] is updated by this procedure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6000
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6001
static int btreeDropTable(Btree *p, int iTable, int *piMoved){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6002
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6003
  MemPage *pPage = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6004
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6005
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6006
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6007
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6008
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6009
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6010
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6011
  /* It is illegal to drop a table if any cursors are open on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6012
  ** database. This is because in auto-vacuum mode the backend may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6013
  ** need to move another root-page to fill a gap left by the deleted
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6014
  ** root page. If an open cursor was using this page a problem would 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6015
  ** occur.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6016
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6017
  if( pBt->pCursor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6018
    return SQLITE_LOCKED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6019
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6020
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6021
  rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6022
  if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6023
  rc = sqlite3BtreeClearTable(p, iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6024
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6025
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6026
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6027
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6028
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6029
  *piMoved = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6030
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6031
  if( iTable>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6032
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6033
    rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6034
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6035
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6036
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6037
      Pgno maxRootPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6038
      rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6039
      if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6040
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6041
        return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6042
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6043
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6044
      if( iTable==maxRootPgno ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6045
        /* If the table being dropped is the table with the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6046
        ** number in the database, put the root page on the free list. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6047
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6048
        rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6049
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6050
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6051
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6052
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6053
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6054
        /* The table being dropped does not have the largest root-page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6055
        ** number in the database. So move the page that does into the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6056
        ** gap left by the deleted root-page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6057
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6058
        MemPage *pMove;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6059
        releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6060
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6061
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6062
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6063
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6064
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6065
        releasePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6066
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6067
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6068
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6069
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6070
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6071
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6072
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6073
        rc = freePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6074
        releasePage(pMove);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6075
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6076
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6077
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6078
        *piMoved = maxRootPgno;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6079
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6080
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6081
      /* Set the new 'max-root-page' value in the database header. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6082
      ** is the old value less one, less one more if that happens to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6083
      ** be a root-page number, less one again if that is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6084
      ** PENDING_BYTE_PAGE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6085
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6086
      maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6087
      if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6088
        maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6089
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6090
      if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6091
        maxRootPgno--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6092
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6093
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6094
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6095
      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6096
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6097
      rc = freePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6098
      releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6099
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6100
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6101
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6102
    /* If sqlite3BtreeDropTable was called on page 1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6103
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6104
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6105
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6106
  return rc;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6107
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6108
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6109
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6110
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6111
  p->pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6112
  rc = btreeDropTable(p, iTable, piMoved);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6113
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6114
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6115
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6116
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6118
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6119
** Read the meta-information out of a database file.  Meta[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6120
** is the number of free pages currently in the database.  Meta[1]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6121
** through meta[15] are available for use by higher layers.  Meta[0]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6122
** is read-only, the others are read/write.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6123
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6124
** The schema layer numbers meta values differently.  At the schema
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6125
** layer (and the SetCookie and ReadCookie opcodes) the number of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6126
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6127
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6128
int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6129
  DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6130
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6131
  unsigned char *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6132
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6133
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6134
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6135
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6136
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6137
  /* Reading a meta-data value requires a read-lock on page 1 (and hence
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6138
  ** the sqlite_master table. We grab this lock regardless of whether or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6139
  ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6140
  ** 1 is treated as a special case by queryTableLock() and lockTable()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6141
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6142
  rc = queryTableLock(p, 1, READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6143
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6144
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6145
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6146
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6147
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6148
  assert( idx>=0 && idx<=15 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6149
  rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6150
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6151
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6152
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6153
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6154
  pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6155
  *pMeta = get4byte(&pP1[36 + idx*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6156
  sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6157
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6158
  /* If autovacuumed is disabled in this build but we are trying to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6159
  ** access an autovacuumed database, then make the database readonly. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6160
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6161
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6162
  if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6163
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6164
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6165
  /* Grab the read-lock on page 1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6166
  rc = lockTable(p, 1, READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6167
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6168
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6169
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6170
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6171
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6172
** Write meta-information back into the database.  Meta[0] is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6173
** read-only and may not be written.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6174
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6175
int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6176
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6177
  unsigned char *pP1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6178
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6179
  assert( idx>=1 && idx<=15 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6180
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6181
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6182
  if( p->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6183
    rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6184
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6185
    assert( pBt->pPage1!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6186
    pP1 = pBt->pPage1->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6187
    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6188
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6189
      put4byte(&pP1[36 + idx*4], iMeta);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6190
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6191
      if( idx==7 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6192
        assert( pBt->autoVacuum || iMeta==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6193
        assert( iMeta==0 || iMeta==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6194
        pBt->incrVacuum = iMeta;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6195
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6196
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6197
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6198
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6199
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6200
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6201
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6202
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6203
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6204
** Return the flag byte at the beginning of the page that the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6205
** is currently pointing to.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6206
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6207
int sqlite3BtreeFlags(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6208
  /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6209
  ** restoreOrClearCursorPosition() here.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6210
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6211
  MemPage *pPage = pCur->pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6212
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6213
  assert( pPage->pBt==pCur->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6214
  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6215
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6216
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6217
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6218
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6219
** Return the pager associated with a BTree.  This routine is used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6220
** testing and debugging only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6221
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6222
Pager *sqlite3BtreePager(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6223
  return p->pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6224
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6225
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6226
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6227
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6228
** Append a message to the error message string.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6229
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6230
static void checkAppendMsg(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6231
  IntegrityCk *pCheck,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6232
  char *zMsg1,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6233
  const char *zFormat,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6234
  ...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6235
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6236
  va_list ap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6237
  char *zMsg2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6238
  if( !pCheck->mxErr ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6239
  pCheck->mxErr--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6240
  pCheck->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6241
  va_start(ap, zFormat);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6242
  zMsg2 = sqlite3VMPrintf(0, zFormat, ap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6243
  va_end(ap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6244
  if( zMsg1==0 ) zMsg1 = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6245
  if( pCheck->zErrMsg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6246
    char *zOld = pCheck->zErrMsg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6247
    pCheck->zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6248
    sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6249
    sqlite3_free(zOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6250
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6251
    sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6252
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6253
  sqlite3_free(zMsg2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6254
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6255
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6256
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6257
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6258
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6259
** Add 1 to the reference count for page iPage.  If this is the second
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6260
** reference to the page, add an error message to pCheck->zErrMsg.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6261
** Return 1 if there are 2 ore more references to the page and 0 if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6262
** if this is the first reference to the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6263
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6264
** Also check that the page number is in bounds.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6265
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6266
static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6267
  if( iPage==0 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6268
  if( iPage>pCheck->nPage || iPage<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6269
    checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6270
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6271
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6272
  if( pCheck->anRef[iPage]==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6273
    checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6274
    return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6275
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6276
  return  (pCheck->anRef[iPage]++)>1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6277
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6278
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6279
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6280
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6281
** Check that the entry in the pointer-map for page iChild maps to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6282
** page iParent, pointer type ptrType. If not, append an error message
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6283
** to pCheck.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6284
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6285
static void checkPtrmap(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6286
  IntegrityCk *pCheck,   /* Integrity check context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6287
  Pgno iChild,           /* Child page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6288
  u8 eType,              /* Expected pointer map type */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6289
  Pgno iParent,          /* Expected pointer map parent page number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6290
  char *zContext         /* Context description (used for error msg) */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6291
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6292
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6293
  u8 ePtrmapType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6294
  Pgno iPtrmapParent;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6296
  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6297
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6298
    checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6299
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6300
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6301
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6302
  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6303
    checkAppendMsg(pCheck, zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6304
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6305
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6306
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6307
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6308
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6309
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6310
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6311
** Check the integrity of the freelist or of an overflow page list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6312
** Verify that the number of pages on the list is N.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6313
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6314
static void checkList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6315
  IntegrityCk *pCheck,  /* Integrity checking context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6316
  int isFreeList,       /* True for a freelist.  False for overflow page list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6317
  int iPage,            /* Page number for first page in the list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6318
  int N,                /* Expected number of pages in the list */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6319
  char *zContext        /* Context for error messages */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6320
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6321
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6322
  int expected = N;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6323
  int iFirst = iPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6324
  while( N-- > 0 && pCheck->mxErr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6325
    DbPage *pOvflPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6326
    unsigned char *pOvflData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6327
    if( iPage<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6328
      checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6329
         "%d of %d pages missing from overflow list starting at %d",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6330
          N+1, expected, iFirst);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6331
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6332
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6333
    if( checkRef(pCheck, iPage, zContext) ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6334
    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6335
      checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6336
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6337
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6338
    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6339
    if( isFreeList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6340
      int n = get4byte(&pOvflData[4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6341
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6342
      if( pCheck->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6343
        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6344
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6345
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6346
      if( n>pCheck->pBt->usableSize/4-8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6347
        checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6348
           "freelist leaf count too big on page %d", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6349
        N--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6350
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6351
        for(i=0; i<n; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6352
          Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6353
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6354
          if( pCheck->pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6355
            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6356
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6357
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6358
          checkRef(pCheck, iFreePage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6359
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6360
        N -= n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6361
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6362
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6363
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6364
    else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6365
      /* If this database supports auto-vacuum and iPage is not the last
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6366
      ** page in this overflow list, check that the pointer-map entry for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6367
      ** the following page matches iPage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6368
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6369
      if( pCheck->pBt->autoVacuum && N>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6370
        i = get4byte(pOvflData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6371
        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6372
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6373
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6374
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6375
    iPage = get4byte(pOvflData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6376
    sqlite3PagerUnref(pOvflPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6377
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6378
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6379
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6380
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6381
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6382
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6383
** Do various sanity checks on a single page of a tree.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6384
** the tree depth.  Root pages return 0.  Parents of root pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6385
** return 1, and so forth.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6386
** 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6387
** These checks are done:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6388
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6389
**      1.  Make sure that cells and freeblocks do not overlap
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6390
**          but combine to completely cover the page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6391
**  NO  2.  Make sure cell keys are in order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6392
**  NO  3.  Make sure no key is less than or equal to zLowerBound.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6393
**  NO  4.  Make sure no key is greater than or equal to zUpperBound.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6394
**      5.  Check the integrity of overflow pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6395
**      6.  Recursively call checkTreePage on all children.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6396
**      7.  Verify that the depth of all children is the same.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6397
**      8.  Make sure this page is at least 33% full or else it is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6398
**          the root of the tree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6399
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6400
static int checkTreePage(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6401
  IntegrityCk *pCheck,  /* Context for the sanity check */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6402
  int iPage,            /* Page number of the page to check */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6403
  MemPage *pParent,     /* Parent page */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6404
  char *zParentContext  /* Parent context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6405
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6406
  MemPage *pPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6407
  int i, rc, depth, d2, pgno, cnt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6408
  int hdr, cellStart;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6409
  int nCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6410
  u8 *data;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6411
  BtShared *pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6412
  int usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6413
  char zContext[100];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6414
  char *hit;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6415
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6416
  sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6417
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6418
  /* Check that the page exists
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6419
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6420
  pBt = pCheck->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6421
  usableSize = pBt->usableSize;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6422
  if( iPage==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6423
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6424
  if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6425
    checkAppendMsg(pCheck, zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6426
       "unable to get the page. error code=%d", rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6427
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6428
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6429
  if( (rc = sqlite3BtreeInitPage(pPage, pParent))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6430
    checkAppendMsg(pCheck, zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6431
                   "sqlite3BtreeInitPage() returns error code %d", rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6432
    releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6433
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6434
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6435
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6436
  /* Check out all the cells.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6437
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6438
  depth = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6439
  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6440
    u8 *pCell;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6441
    int sz;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6442
    CellInfo info;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6443
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6444
    /* Check payload overflow pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6445
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6446
    sqlite3_snprintf(sizeof(zContext), zContext,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6447
             "On tree page %d cell %d: ", iPage, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6448
    pCell = findCell(pPage,i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6449
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6450
    sz = info.nData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6451
    if( !pPage->intKey ) sz += info.nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6452
    assert( sz==info.nPayload );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6453
    if( sz>info.nLocal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6454
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6455
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6456
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6457
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6458
        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6459
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6460
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6461
      checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6462
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6463
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6464
    /* Check sanity of left child page.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6465
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6466
    if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6467
      pgno = get4byte(pCell);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6468
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6469
      if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6470
        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6471
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6472
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6473
      d2 = checkTreePage(pCheck,pgno,pPage,zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6474
      if( i>0 && d2!=depth ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6475
        checkAppendMsg(pCheck, zContext, "Child page depth differs");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6476
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6477
      depth = d2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6478
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6479
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6480
  if( !pPage->leaf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6481
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6482
    sqlite3_snprintf(sizeof(zContext), zContext, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6483
                     "On page %d at right child: ", iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6484
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6485
    if( pBt->autoVacuum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6486
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6487
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6488
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6489
    checkTreePage(pCheck, pgno, pPage, zContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6490
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6491
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6492
  /* Check for complete coverage of the page
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6493
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6494
  data = pPage->aData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6495
  hdr = pPage->hdrOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6496
  hit = (char*)sqlite3MallocZero( usableSize );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6497
  if( hit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6498
    memset(hit, 1, get2byte(&data[hdr+5]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6499
    nCell = get2byte(&data[hdr+3]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6500
    cellStart = hdr + 12 - 4*pPage->leaf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6501
    for(i=0; i<nCell; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6502
      int pc = get2byte(&data[cellStart+i*2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6503
      int size = cellSizePtr(pPage, &data[pc]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6504
      int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6505
      if( (pc+size-1)>=usableSize || pc<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6506
        checkAppendMsg(pCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6507
            "Corruption detected in cell %d on page %d",i,iPage,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6508
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6509
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6510
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6511
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6512
    for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i<usableSize && cnt<10000; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6513
           cnt++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6514
      int size = get2byte(&data[i+2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6515
      int j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6516
      if( (i+size-1)>=usableSize || i<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6517
        checkAppendMsg(pCheck, 0,  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6518
            "Corruption detected in cell %d on page %d",i,iPage,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6519
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6520
        for(j=i+size-1; j>=i; j--) hit[j]++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6521
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6522
      i = get2byte(&data[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6523
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6524
    for(i=cnt=0; i<usableSize; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6525
      if( hit[i]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6526
        cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6527
      }else if( hit[i]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6528
        checkAppendMsg(pCheck, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6529
          "Multiple uses for byte %d of page %d", i, iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6530
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6531
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6532
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6533
    if( cnt!=data[hdr+7] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6534
      checkAppendMsg(pCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6535
          "Fragmented space is %d byte reported as %d on page %d",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6536
          cnt, data[hdr+7], iPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6537
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6538
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6539
  sqlite3_free(hit);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6540
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6541
  releasePage(pPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6542
  return depth+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6543
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6544
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6545
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6546
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6547
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6548
** This routine does a complete check of the given BTree file.  aRoot[] is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6549
** an array of pages numbers were each page number is the root page of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6550
** a table.  nRoot is the number of entries in aRoot.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6552
** If everything checks out, this routine returns NULL.  If something is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6553
** amiss, an error message is written into memory obtained from malloc()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6554
** and a pointer to that error message is returned.  The calling function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6555
** is responsible for freeing the error message when it is done.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6556
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6557
char *sqlite3BtreeIntegrityCheck(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6558
  Btree *p,     /* The btree to be checked */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6559
  int *aRoot,   /* An array of root pages numbers for individual trees */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6560
  int nRoot,    /* Number of entries in aRoot[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6561
  int mxErr,    /* Stop reporting errors after this many */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6562
  int *pnErr    /* Write number of errors seen to this variable */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6563
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6564
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6565
  int nRef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6566
  IntegrityCk sCheck;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6567
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6568
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6569
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6570
  pBt->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6571
  nRef = sqlite3PagerRefcount(pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6572
  if( lockBtreeWithRetry(p)!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6573
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6574
    return sqlite3StrDup("Unable to acquire a read lock on the database");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6575
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6576
  sCheck.pBt = pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6577
  sCheck.pPager = pBt->pPager;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6578
  sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6579
  sCheck.mxErr = mxErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6580
  sCheck.nErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6581
  *pnErr = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6582
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6583
  if( pBt->nTrunc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6584
    sCheck.nPage = pBt->nTrunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6585
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6586
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6587
  if( sCheck.nPage==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6588
    unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6589
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6590
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6591
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6592
  sCheck.anRef = (int*)sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6593
  if( !sCheck.anRef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6594
    unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6595
    *pnErr = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6596
    sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6597
    return sqlite3MPrintf(p->db, "Unable to malloc %d bytes", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6598
        (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6599
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6600
  for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6601
  i = PENDING_BYTE_PAGE(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6602
  if( i<=sCheck.nPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6603
    sCheck.anRef[i] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6604
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6605
  sCheck.zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6606
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6607
  /* Check the integrity of the freelist
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6608
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6609
  checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6610
            get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6611
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6612
  /* Check all the tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6613
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6614
  for(i=0; i<nRoot && sCheck.mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6615
    if( aRoot[i]==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6616
#ifndef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6617
    if( pBt->autoVacuum && aRoot[i]>1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6618
      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6619
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6620
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6621
    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6622
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6623
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6624
  /* Make sure every page in the file is referenced
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6625
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6626
  for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6627
#ifdef SQLITE_OMIT_AUTOVACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6628
    if( sCheck.anRef[i]==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6629
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6630
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6631
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6632
    /* If the database supports auto-vacuum, make sure no tables contain
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6633
    ** references to pointer-map pages.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6634
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6635
    if( sCheck.anRef[i]==0 && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6636
       (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6637
      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6638
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6639
    if( sCheck.anRef[i]!=0 && 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6640
       (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6641
      checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6642
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6643
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6644
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6645
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6646
  /* Make sure this analysis did not leave any unref() pages
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6647
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6648
  unlockBtreeIfUnused(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6649
  if( nRef != sqlite3PagerRefcount(pBt->pPager) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6650
    checkAppendMsg(&sCheck, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6651
      "Outstanding page count goes from %d to %d during this analysis",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6652
      nRef, sqlite3PagerRefcount(pBt->pPager)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6653
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6654
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6655
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6656
  /* Clean  up and report errors.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6657
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6658
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6659
  sqlite3_free(sCheck.anRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6660
  *pnErr = sCheck.nErr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6661
  return sCheck.zErrMsg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6662
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6663
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6664
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6665
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6666
** Return the full pathname of the underlying database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6667
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6668
** The pager filename is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6669
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6670
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6671
const char *sqlite3BtreeGetFilename(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6672
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6673
  return sqlite3PagerFilename(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6674
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6675
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6676
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6677
** Return the pathname of the directory that contains the database file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6678
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6679
** The pager directory name is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6680
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6681
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6682
const char *sqlite3BtreeGetDirname(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6683
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6684
  return sqlite3PagerDirname(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6685
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6686
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6687
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6688
** Return the pathname of the journal file for this database. The return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6689
** value of this routine is the same regardless of whether the journal file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6690
** has been created or not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6691
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6692
** The pager journal filename is invariant as long as the pager is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6693
** open so it is safe to access without the BtShared mutex.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6694
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6695
const char *sqlite3BtreeGetJournalname(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6696
  assert( p->pBt->pPager!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6697
  return sqlite3PagerJournalname(p->pBt->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6698
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6699
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6700
#ifndef SQLITE_OMIT_VACUUM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6701
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6702
** Copy the complete content of pBtFrom into pBtTo.  A transaction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6703
** must be active for both files.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6704
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6705
** The size of file pBtFrom may be reduced by this operation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6706
** If anything goes wrong, the transaction on pBtFrom is rolled back.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6707
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6708
static int btreeCopyFile(Btree *pTo, Btree *pFrom){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6709
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6710
  Pgno i, nPage, nToPage, iSkip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6711
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6712
  BtShared *pBtTo = pTo->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6713
  BtShared *pBtFrom = pFrom->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6714
  pBtTo->db = pTo->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6715
  pBtFrom->db = pFrom->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6716
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6717
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6718
  if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6719
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6720
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6721
  if( pBtTo->pCursor ) return SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6722
  nToPage = sqlite3PagerPagecount(pBtTo->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6723
  nPage = sqlite3PagerPagecount(pBtFrom->pPager);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6724
  iSkip = PENDING_BYTE_PAGE(pBtTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6725
  for(i=1; rc==SQLITE_OK && i<=nPage; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6726
    DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6727
    if( i==iSkip ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6728
    rc = sqlite3PagerGet(pBtFrom->pPager, i, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6729
    if( rc ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6730
    rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6731
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6732
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6733
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6734
  /* If the file is shrinking, journal the pages that are being truncated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6735
  ** so that they can be rolled back if the commit fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6736
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6737
  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6738
    DbPage *pDbPage;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6739
    if( i==iSkip ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6740
    rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6741
    if( rc ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6742
    rc = sqlite3PagerWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6743
    sqlite3PagerDontWrite(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6744
    /* Yeah.  It seems wierd to call DontWrite() right after Write().  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6745
    ** that is because the names of those procedures do not exactly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6746
    ** represent what they do.  Write() really means "put this page in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6747
    ** rollback journal and mark it as dirty so that it will be written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6748
    ** to the database file later."  DontWrite() undoes the second part of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6749
    ** that and prevents the page from being written to the database.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6750
    ** page is still on the rollback journal, though.  And that is the whole
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6751
    ** point of this loop: to put pages on the rollback journal. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6752
    sqlite3PagerUnref(pDbPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6753
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6754
  if( !rc && nPage<nToPage ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6755
    rc = sqlite3PagerTruncate(pBtTo->pPager, nPage);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6756
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6757
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6758
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6759
    sqlite3BtreeRollback(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6760
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6761
  return rc;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6762
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6763
int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6764
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6765
  sqlite3BtreeEnter(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6766
  sqlite3BtreeEnter(pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6767
  rc = btreeCopyFile(pTo, pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6768
  sqlite3BtreeLeave(pFrom);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6769
  sqlite3BtreeLeave(pTo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6770
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6771
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6772
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6773
#endif /* SQLITE_OMIT_VACUUM */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6774
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6775
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6776
** Return non-zero if a transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6777
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6778
int sqlite3BtreeIsInTrans(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6779
  assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6780
  return (p && (p->inTrans==TRANS_WRITE));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6781
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6782
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6783
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6784
** Return non-zero if a statement transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6785
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6786
int sqlite3BtreeIsInStmt(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6787
  assert( sqlite3BtreeHoldsMutex(p) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6788
  return (p->pBt && p->pBt->inStmt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6789
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6790
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6791
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6792
** Return non-zero if a read (or write) transaction is active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6793
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6794
int sqlite3BtreeIsInReadTrans(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6795
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6796
  return (p && (p->inTrans!=TRANS_NONE));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6797
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6798
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6799
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6800
** This function returns a pointer to a blob of memory associated with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6801
** a single shared-btree. The memory is used by client code for its own
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6802
** purposes (for example, to store a high-level schema associated with 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6803
** the shared-btree). The btree layer manages reference counting issues.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6804
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6805
** The first time this is called on a shared-btree, nBytes bytes of memory
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6806
** are allocated, zeroed, and returned to the caller. For each subsequent 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6807
** call the nBytes parameter is ignored and a pointer to the same blob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6808
** of memory returned. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6809
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6810
** Just before the shared-btree is closed, the function passed as the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6811
** xFree argument when the memory allocation was made is invoked on the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6812
** blob of allocated memory. This function should not call sqlite3_free()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6813
** on the memory, the btree layer does that.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6814
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6815
void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6816
  BtShared *pBt = p->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6817
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6818
  if( !pBt->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6819
    pBt->pSchema = sqlite3MallocZero(nBytes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6820
    pBt->xFreeSchema = xFree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6821
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6822
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6823
  return pBt->pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6824
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6825
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6826
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6827
** Return true if another user of the same shared btree as the argument
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6828
** handle holds an exclusive lock on the sqlite_master table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6829
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6830
int sqlite3BtreeSchemaLocked(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6831
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6832
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6833
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6834
  rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6835
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6836
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6837
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6838
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6839
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6840
#ifndef SQLITE_OMIT_SHARED_CACHE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6841
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6842
** Obtain a lock on the table whose root page is iTab.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6843
** lock is a write lock if isWritelock is true or a read lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6844
** if it is false.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6845
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6846
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6847
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6848
  u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6849
  sqlite3BtreeEnter(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6850
  rc = queryTableLock(p, iTab, lockType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6851
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6852
    rc = lockTable(p, iTab, lockType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6853
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6854
  sqlite3BtreeLeave(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6855
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6856
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6857
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6858
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6859
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6860
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6861
** Argument pCsr must be a cursor opened for writing on an 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6862
** INTKEY table currently pointing at a valid table entry. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6863
** This function modifies the data stored as part of that entry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6864
** Only the data content may only be modified, it is not possible
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6865
** to change the length of the data stored.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6866
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6867
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6868
  assert( cursorHoldsMutex(pCsr) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6869
  assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6870
  assert(pCsr->isIncrblobHandle);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6871
  if( pCsr->eState>=CURSOR_REQUIRESEEK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6872
    if( pCsr->eState==CURSOR_FAULT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6873
      return pCsr->skip;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6874
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6875
      return SQLITE_ABORT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6876
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6877
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6879
  /* Check some preconditions: 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6880
  **   (a) the cursor is open for writing,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6881
  **   (b) there is no read-lock on the table being modified and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6882
  **   (c) the cursor points at a valid row of an intKey table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6883
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6884
  if( !pCsr->wrFlag ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6885
    return SQLITE_READONLY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6886
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6887
  assert( !pCsr->pBt->readOnly 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6888
          && pCsr->pBt->inTransaction==TRANS_WRITE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6889
  if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6890
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6891
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6892
  if( pCsr->eState==CURSOR_INVALID || !pCsr->pPage->intKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6893
    return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6894
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6895
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6896
  return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6897
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6898
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6899
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6900
** Set a flag on this cursor to cache the locations of pages from the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6901
** overflow list for the current row. This is used by cursors opened
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6902
** for incremental blob IO only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6903
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6904
** This function sets a flag only. The actual page location cache
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6905
** (stored in BtCursor.aOverflow[]) is allocated and used by function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6906
** accessPayload() (the worker function for sqlite3BtreeData() and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6907
** sqlite3BtreePutData()).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6908
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6909
void sqlite3BtreeCacheOverflow(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6910
  assert( cursorHoldsMutex(pCur) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6911
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6912
  assert(!pCur->isIncrblobHandle);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6913
  assert(!pCur->aOverflow);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6914
  pCur->isIncrblobHandle = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6915
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  6916
#endif