/ Check-in [6adb6078]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Perpare to fork SQLite2.0 develop into a separate tree (CVS 183)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6adb6078871114ba19ab601bb94d43ff9e03e43f
User & Date: drh 2001-02-11 16:56:24
Context
2001-02-11
16:58
Perpare to fork SQLite2.0 develop into a separate tree (CVS 184) check-in: 4f00e27f user: drh tags: trunk
16:56
Perpare to fork SQLite2.0 develop into a separate tree (CVS 183) check-in: 6adb6078 user: drh tags: trunk
2001-02-06
14:10
hi (CVS 1716) check-in: 5128135c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to VERSION.

     1         -1.1.0
            1  +1.0.20

Deleted src/db.c.

     1         -/*
     2         -** Copyright (c) 2001 D. Richard Hipp
     3         -**
     4         -** This program is free software; you can redistribute it and/or
     5         -** modify it under the terms of the GNU General Public
     6         -** License as published by the Free Software Foundation; either
     7         -** version 2 of the License, or (at your option) any later version.
     8         -**
     9         -** This program is distributed in the hope that it will be useful,
    10         -** but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    12         -** General Public License for more details.
    13         -** 
    14         -** You should have received a copy of the GNU General Public
    15         -** License along with this library; if not, write to the
    16         -** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    17         -** Boston, MA  02111-1307, USA.
    18         -**
    19         -** Author contact information:
    20         -**   drh@hwaci.com
    21         -**   http://www.hwaci.com/drh/
    22         -**
    23         -*************************************************************************
    24         -** $Id: db.c,v 1.6 2001/01/31 13:28:08 drh Exp $
    25         -*/
    26         -#include "sqliteInt.h"
    27         -#include "pg.h"
    28         -
    29         -/*
    30         -** Everything we need to know about an open database
    31         -*/
    32         -struct Db {
    33         -  Pgr *pPgr;            /* The pager for the database */
    34         -  DbCursor *pCursor;    /* All open cursors */
    35         -  int inTransaction;    /* True if a transaction is in progress */
    36         -  u32 freeList;         /* List of free blocks */
    37         -  int nTable;           /* Number of slots in aContent[] */
    38         -  u32 *aTable;          /* Root page numbers for all tables */
    39         -};
    40         -
    41         -/*
    42         -** The maximum depth of a cursor
    43         -*/
    44         -#define MX_LEVEL 10
    45         -
    46         -/*
    47         -** Within a cursor, each level off the search tree is an instance of
    48         -** this structure.
    49         -*/
    50         -typedef struct DbIdxpt DbIdxpt;
    51         -struct DbIdxpt {
    52         -  int pgno;         /* The page number */
    53         -  u32 *aPage;       /* The page data */
    54         -  int idx;          /* Index into pPage[] */
    55         -};
    56         -
    57         -/*
    58         -** Everything we need to know about a cursor
    59         -*/
    60         -struct DbCursor {
    61         -  Db *pDb;                      /* The whole database */
    62         -  DbCursor *pPrev, *pNext;      /* Linked list of all cursors */
    63         -  u32 rootPgno;                 /* Root page of table for this cursor */
    64         -  int onEntry;                  /* True if pointing to a table entry */
    65         -  int nLevel;                   /* Number of levels of indexing used */
    66         -  DbIdxpt aLevel[MX_LEVEL];     /* The index levels */
    67         -};
    68         -
    69         -/*
    70         -** Data layouts
    71         -**
    72         -** LEAF:
    73         -**    x[0]          Magic number: BLOCK_LEAF
    74         -**    x[1]          If root page, total number of entries in this table
    75         -**    ...           One or more entries follow the leaf.
    76         -**
    77         -** Entry:
    78         -**    x[N+0]        Number of u32-sized words in this entry
    79         -**    x[N+1]        Hash value for this entry
    80         -**    x[N+2]        Number of bytes of key in the payload
    81         -**    x[N+3]        Number of bytes of data in the payload
    82         -**    x{N+4]...     The payload area.
    83         -**
    84         -** INDEX:
    85         -**    x[0]          Magic number: BLOCK_INDEX
    86         -**    x[1]          If root page: total number of entries in this table
    87         -**    x[2]          Number of slots in this index (Max value of N)
    88         -**    x[2*N+3]      Page number containing entries with hash <= x[2*N+4]
    89         -**    x[2*N+4]      The maximum hash value for entries on page x[2*N+3].
    90         -**
    91         -** FREE:
    92         -**    x[0]          Magic number: BLOCK_FREE
    93         -**    x[1]          Page number of the next free block on the free list
    94         -**
    95         -** PAGE1:
    96         -**    x[0]          Magic number: BLOCK_PAGE1
    97         -**    x[1]          First page of the freelist
    98         -**    x[2]          Number of tables in this database
    99         -**    x[N+3]        Root page for table N
   100         -
   101         -/*
   102         -** The first word of every page is some combination of these values
   103         -** used to indicate its function.
   104         -*/
   105         -#define BLOCK_PAGE1            0x24e47191
   106         -#define BLOCK_INDEX            0x7ac53b46
   107         -#define BLOCK_LEAF             0x60c45eef
   108         -#define BLOCK_FREE             0x5b2dda47
   109         -
   110         -/*
   111         -** The number of u32-sized objects that will fit on one page.
   112         -*/
   113         -#define U32_PER_PAGE  (SQLITE_PAGE_SIZE/sizeof(u32))
   114         -
   115         -/*
   116         -** Number of direct overflow pages per database entry
   117         -*/
   118         -#define N_DIRECT  10
   119         -
   120         -/*
   121         -** The maximum amount of payload (in bytes) that will fit on on the same
   122         -** page as a leaf.  In other words, the maximum amount of payload
   123         -** that does not require any overflow pages.
   124         -**
   125         -** This size is chosen so that a least 3 entry will fit on every 
   126         -** leaf.  That guarantees it will always be possible to add a new
   127         -** entry after a page split.
   128         -*/
   129         -#define LOCAL_PAYLOAD (((U32_PER_PAGE-2)/3 - (6+N_DIRECT))*sizeof(u32))
   130         -
   131         -/*
   132         -** Allocate a new page.  Return both the page number and a pointer
   133         -** to the page data.  The calling function is responsible for unref-ing
   134         -** the page when it is no longer needed.
   135         -**
   136         -** The page is obtained from the freelist if there is anything there.
   137         -** If the freelist is empty, the new page comes from the end of the
   138         -** database file.
   139         -*/
   140         -int allocPage(Db *pDb, u32 *pPgno, u32 **ppPage){
   141         -  u32 pgno;
   142         -  int rc;
   143         -
   144         -  if( pDb->aTable==0 ) return SQLITE_NOMEM;
   145         -
   146         -  /* Try to reuse a page from the freelist
   147         -  */
   148         -  if( pDb->freeList==0 ){
   149         -    u32 *pPage;
   150         -    rc = sqlitePgGet(pDb->pPgr, pDb->freeList, &pPage);
   151         -    if( rc==SQLITE_OK ){
   152         -      if( pPage[0]==BLOCK_FREE ){
   153         -        *pPgno = pDb->freeList;
   154         -        *ppPage = aPage;
   155         -        pDb->freeList = aPage[1];
   156         -        memset(*ppPage, 0, SQLITE_PAGE_SIZE);
   157         -        return SQLITE_OK;
   158         -      }
   159         -      /* This only happens if we have database corruption */
   160         -      sqlitePgUnref(pPage);
   161         -    }
   162         -  }
   163         -
   164         -  /* If the freelist is empty, or we cannot access it,
   165         -  ** then allocate a new page from the end of the file.
   166         -  */
   167         -  if( (rc = sqlitePgCount(pDb->pPgr, &pgno))==SQLITE_OK &&
   168         -      (rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage))==SQLITE_OK ){
   169         -    *pPgno = pgno;
   170         -    memset(*ppPage, 0, SQLITE_PAGE_SIZE);
   171         -    return SQLITE_OK;
   172         -  }
   173         -  return rc;
   174         -}
   175         -
   176         -/*
   177         -** Return a page to the freelist and dereference the page.
   178         -*/
   179         -static void freePage(DB *pDb, u32 pgno, u32 *aPage){
   180         -  if( pgno==0 ) return
   181         -  if( aPage==0 ){
   182         -    int rc;
   183         -    rc = sqlitePgGet(pDb->pPgr, pgno, &aPage);
   184         -    if( rc!=SQLITE_OK ) return;
   185         -  }
   186         -  assert( sqlitePgNum(aPage)==pgno );
   187         -  aPage[0] = BLOCK_FREE;
   188         -  aPage[1] = pDb->freeList;
   189         -  pDb->freeList = pgno;
   190         -  memset(&aPage[2], 0, SQLITE_PAGE_SIZE - 2*sizeof(u32));
   191         -  sqlitePgTouch(aPage);
   192         -  sqlitePgUnref(aPage);
   193         -}
   194         -
   195         -/*
   196         -** Return the number of bytes of payload storage required on the leaf
   197         -** node to hold the amount of payload specified by the argument.
   198         -** Overflow pages do not count, only memory on the leaf page.
   199         -**
   200         -** Return -1 if nTotal is more than sqlite is able to store.
   201         -*/
   202         -static int payloadLocalSize(int nTotal){
   203         -  int nLocal, i;
   204         -  if( nTotal<0 ) nTotal = 0;
   205         -  if( nTotal <= LOCAL_PAYLOAD ){
   206         -    /* All the data fits on the leaf page */
   207         -    return (nTotal + 3)/4;
   208         -  }
   209         -  nLocal = LOCAL_PAYLOAD;
   210         -  nTotal -= LOCAL_PAYLOAD;
   211         -  if( nTotal < 10*SQLITE_PAGE_SIZE ){
   212         -    return nLocal + ((nTotal+SQLITE_PAGE_SIZE-1)/SQLITE_PAGE_SIZE)*sizeof(u32);
   213         -  }
   214         -  nLocal += N_DIRECT*sizeof(u32);
   215         -  nTotal -= N_DIRECT*SQLITE_PAGE_SIZE;
   216         -  if( nTotal < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   217         -    return nLocal + sizeof(u32);
   218         -  }
   219         -  nLocal += sizeof(u32);
   220         -  nTotal -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
   221         -  if( nTotal < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   222         -    return nLocal + sizeof(u32);
   223         -  }
   224         -  return -1;  /* This payload will not fit. */
   225         -}
   226         -
   227         -/*
   228         -** Read data from the payload area.
   229         -**
   230         -** aPage points directly at the beginning of the payload.  No bounds 
   231         -** checking is done on offset or amt -- it is assumed that the payload
   232         -** area is big enough to accomodate.
   233         -*/
   234         -static int payloadRead(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
   235         -  int rc;
   236         -  int tomove;
   237         -  int i;
   238         -
   239         -  /* First read local data off of the leaf page itself.
   240         -  ** This is all that ever happens in 99% of accesses.
   241         -  */
   242         -  assert( offset>=0 && amt>=0 );
   243         -  if( offset < LOCAL_PAYLOAD ){
   244         -    /* Data stored directly in the leaf block of the BTree */
   245         -    if( amt+offset>LOCAL_PAYLOAD ){
   246         -      tomove = LOCAL_PAYLOAD - offset;
   247         -    }else{
   248         -      tomove = amt;
   249         -    }
   250         -    memcpy(pBuf, &((char*)aPage)[offset], tomove);
   251         -    pBuf = &((char*)pBuf)[tomove];
   252         -    offset += tomove;
   253         -    amt -= tomove;
   254         -    if( amt<=0 ) return SQLITE_OK;
   255         -  }
   256         -  offset -= LOCAL_PAYLOAD;
   257         -  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
   258         -
   259         -  /* If not all of the data fits locally, read from the first
   260         -  ** ten direct-access overflow pages.
   261         -  */
   262         -  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
   263         -    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
   264         -      char *aData;
   265         -      base = offset - i*SQLITE_PAGE_SIZE;
   266         -      rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
   267         -      if( rc!=SQLITE_OK ) return rc;
   268         -      if( amt+base > SQLITE_PAGE_SIZE ){
   269         -        tomove = SQLITE_PAGE_SIZE - base;
   270         -      }else{
   271         -        tomove = amt;
   272         -      }
   273         -      memcpy(pBuf, &aData[base], tomove);
   274         -      sqlitePgUnref(aData);
   275         -      pBuf = &((char*)pBuf)[tomove];
   276         -      amt -= tomove;
   277         -    }
   278         -  }
   279         -  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
   280         -  aPage += N_DIRECT;
   281         -
   282         -  /* If the first N_DIRECT overflow pages do not contain everything, then
   283         -  ** read from an overflow page that is filled with pointer to
   284         -  ** U32_PER_PAGE more overflow pages.
   285         -  */
   286         -  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   287         -    u32 *indirPage;
   288         -    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
   289         -    if( rc!=SQLITE_OK ) return rc;
   290         -    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
   291         -      int base;
   292         -      char *aData;
   293         -      base = offset - i*SQLITE_PAGE_SIZE;
   294         -      rc = sqlitePgGet(pDb->pPgr, indirPage[idx], &aData);
   295         -      if( rc!=SQLITE_OK ) break;
   296         -      if( amt+base > SQLITE_PAGE_SIZE ){
   297         -        tomove = SQLITE_PAGE_SIZE - base;
   298         -      }else{
   299         -        tomove = amt;
   300         -      }
   301         -      memcpy(pBuf, &aData[base], tomove);
   302         -      sqlitePgUnref(aData);
   303         -      pBuf = &((char*)pBuf)[tomove];
   304         -      amt -= tomove;
   305         -    }
   306         -    sqlitePgUnref(indirPage);
   307         -    if( rc!=SQLITE_OK ) return rc;
   308         -    if( amt<=0 ) return SQLITE_OK;
   309         -  }
   310         -  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
   311         -  aPage++;
   312         -
   313         -  /* If there is still more data, then read using a double-indirect
   314         -  ** overflow.  The overflow page points to U32_PER_PAGE additional
   315         -  ** overflow pages, each of which pointer to U32_PER_PAGE more overflow
   316         -  ** pages which contain data.
   317         -  **
   318         -  ** This is hard to test.  To exercise this code, you have to make
   319         -  ** a database entry of more than 273336 bytes in side, assuming a
   320         -  ** pagesize of 1024 bytes and 10 direct overflow pages.  By the 
   321         -  ** time this code runs, you have already used 267 overflow pages.
   322         -  */
   323         -  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   324         -    u32 *dblIndirPage;
   325         -    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
   326         -    if( rc!=SQLITE_OK ) return rc;
   327         -    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
   328         -    for(; i<U32_PER_PAGE && amt>0; i++){
   329         -      u32 *indirPage;
   330         -      int basis;
   331         -      int j;
   332         -      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
   333         -      if( rc!=SQLITE_OK ) break;
   334         -      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
   335         -      j = (offset - basis)/SQLITE_PAGE_SIZE;
   336         -      for(; j<U32_PER_PAGE && amt>0; j++){
   337         -        char *aData;
   338         -        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
   339         -        rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
   340         -        if( rc!=SQLITE_OK ) break;
   341         -        if( amt+base > SQLITE_PAGE_SIZE ){
   342         -          tomove = SQLITE_PAGE_SIZE - base;
   343         -        }else{
   344         -          tomove = amt;
   345         -        }
   346         -        memcpy(pBuf, &aData[base], tomove);
   347         -        sqlitePgUnref(aData);
   348         -        pBuf = &((char*)pBuf)[tomove];
   349         -        amt -= tomove;
   350         -      }
   351         -      sqlitePgUnref(indirPage);
   352         -      if( rc!=SQLITE_OK ) break;
   353         -    }
   354         -    sqlitePgUnref(dblIndirPage);
   355         -  }
   356         -
   357         -  /* Anything beyond the double-indirect pages, just fill in with
   358         -  ** zeros.  You have to write 67382200 bytes to go past the
   359         -  ** double-indirect pages, assuming a 1024 byte page size.
   360         -  */
   361         -  if( amt>0 ) memset(pBuf, 0, amt);
   362         -  return SQLITE_OK;
   363         -}
   364         -
   365         -/*
   366         -** Write data into the payload area.
   367         -**
   368         -** If pages have already been allocated for the payload, they are
   369         -** simply overwritten.  New pages are allocated as necessary to
   370         -** fill in gaps.  sqlitePgTouch() is called on all overflow pages,
   371         -** but the calling function must invoke sqlitePgTouch() for aPage
   372         -** itself.
   373         -*/
   374         -static int payloadWrite(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
   375         -  assert( offset>=0 && amt>=0 );
   376         -
   377         -  /* Local data
   378         -  */
   379         -  if( offset < LOCAL_PAYLOAD ){
   380         -    if( amt+offset>LOCAL_PAYLOAD ){
   381         -      tomove = LOCAL_PAYLOAD - offset;
   382         -    }else{
   383         -      tomove = amt;
   384         -    }
   385         -    memcpy(&((char*)aPage)[offset], pBuf, tomove);
   386         -    pBuf = &((char*)pBuf)[tomove];
   387         -    offset += tomove;
   388         -    amt -= tomove;
   389         -    if( amt<=0 ) return SQLITE_OK;
   390         -  }
   391         -  offset -= LOCAL_PAYLOAD;
   392         -  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
   393         -
   394         -  /* Direct overflow pages
   395         -  */
   396         -  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
   397         -    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
   398         -      base = offset - i*SQLITE_PAGE_SIZE;
   399         -      if( aPage[i] ){
   400         -        rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
   401         -      }else{
   402         -        rc = allocPage(pDb, &aPage[i], &aData);
   403         -      }
   404         -      if( rc!=SQLITE_OK ) return rc;
   405         -      if( amt+base > SQLITE_PAGE_SIZE ){
   406         -        tomove = SQLITE_PAGE_SIZE - base;
   407         -      }else{
   408         -        tomove = amt;
   409         -      }
   410         -      memcpy(&aData[base], pBuf, tomove);
   411         -      sqlitePgTouch(aData);
   412         -      sqlitePgUnref(aData);
   413         -      pBuf = &((char*)pBuf)[tomove];
   414         -      amt -= tomove;
   415         -    }
   416         -    if( amt<=0 ) return SQLITE_OK;
   417         -  }
   418         -  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
   419         -  aPage += N_DIRECT;
   420         -
   421         -  /* Indirect overflow pages
   422         -  */
   423         -  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   424         -    u32 *indirPage;
   425         -    if( aPage[0] ){
   426         -      rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
   427         -    }else{
   428         -      rc = allocPage(pDb, &aPage[0], &indirPage);
   429         -    }
   430         -    if( rc!=SQLITE_OK ) return rc;
   431         -    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
   432         -      int base;
   433         -      char *aData;
   434         -      base = offset - i*SQLITE_PAGE_SIZE;
   435         -      if( indirPage[i] ){
   436         -        rc = sqlitePgGet(pDb->pPgr, indirPage[i], &aData);
   437         -      }else{
   438         -        rc = allocPage(pDb, &indirPage[i], &aData);
   439         -        sqlitePgTouch(indirPage);
   440         -      }
   441         -      if( rc!=SQLITE_OK ) break;
   442         -      if( amt+base > SQLITE_PAGE_SIZE ){
   443         -        tomove = SQLITE_PAGE_SIZE - base;
   444         -      }else{
   445         -        tomove = amt;
   446         -      }
   447         -      memcpy(&aData[base], pBuf, tomove);
   448         -      sqlitePgUnref(aData);
   449         -      pBuf = &((char*)pBuf)[tomove];
   450         -      amt -= tomove;
   451         -    }
   452         -    sqlitePgUnref(indirPage);
   453         -    if( rc!=SQLITE_OK ) return rc;
   454         -    if( amt<=0 ) return SQLITE_OK;
   455         -  }
   456         -  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
   457         -  aPage++;
   458         -
   459         -  /* Double-indirect overflow pages
   460         -  */
   461         -  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
   462         -    u32 *dblIndirPage;
   463         -    if( aPage[0] ){
   464         -      rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
   465         -    }else{
   466         -      rc = allocPage(pDb, &aPage[0], &dblIndirPage);
   467         -    }
   468         -    if( rc!=SQLITE_OK ) return rc;
   469         -    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
   470         -    for(; i<U32_PER_PAGE && amt>0; i++){
   471         -      u32 *indirPage;
   472         -      int basis;
   473         -      int j;
   474         -      if( aPage[0] ){
   475         -        rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
   476         -      }else{
   477         -        rc = allocPage(pDb, &aPage[0], &dblIndirPage);
   478         -        sqlitePgTouch(dblIndirPage);
   479         -      }
   480         -      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
   481         -      if( rc!=SQLITE_OK ) break;
   482         -      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
   483         -      j = (offset - basis)/SQLITE_PAGE_SIZE;
   484         -      for(; j<U32_PER_PAGE && amt>0; j++){
   485         -        char *aData;
   486         -        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
   487         -        if( indirPage[j] ){
   488         -          rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
   489         -        }else{
   490         -          rc = allocPage(pDb, &indirPage[j], &aData);
   491         -          sqlitePgTouch(indirPage);
   492         -        }
   493         -        if( rc!=SQLITE_OK ) break;
   494         -        if( amt+base > SQLITE_PAGE_SIZE ){
   495         -          tomove = SQLITE_PAGE_SIZE - base;
   496         -        }else{
   497         -          tomove = amt;
   498         -        }
   499         -        memcpy(&aData[base], pBuf, tomove);
   500         -        sqlitePgTouch(aData);
   501         -        sqlitePgUnref(aData);
   502         -        pBuf = &((char*)pBuf)[tomove];
   503         -        amt -= tomove;
   504         -      }
   505         -      sqlitePgUnref(indirPage);
   506         -      if( rc!=SQLITE_OK ) break;
   507         -    }
   508         -    sqlitePgUnref(dblIndirPage);
   509         -  }
   510         -
   511         -  return SQLITE_OK;
   512         -}
   513         -
   514         -/*
   515         -** Resize the payload area.  If the payload area descreases in size,
   516         -** this routine deallocates unused overflow pages.  If the payload
   517         -** area increases in size, this routine is a no-op.
   518         -*/
   519         -static int payloadResize(Db *pDb, u32 *aPage, int oldSize, int newSize){
   520         -  int i, j;          /* Loop counters */
   521         -  int first, last;   /* Indices of first and last pages to be freed */
   522         -  int rc;            /* Return code from sqlitePgGet() */
   523         -
   524         -  /* Skip over the local data.  We do not need to free it.
   525         -  */
   526         -  if( newSize>=oldSize ) return SQLITE_OK;
   527         -  oldSize -= LOCAL_PAYLOAD;
   528         -  if( oldSize<=0 ) return SQLITE_OK;
   529         -  newSize -= LOCAL_PAYLOAD;
   530         -  aPage += LOCAL_PAYLOAD/sizeof(u32);
   531         -
   532         -  /* Compute the indices of the first and last overflow pages to
   533         -  ** be freed.
   534         -  */
   535         -  first = (newSize - 1)/SQLITE_PAGE_SIZE + 1;
   536         -  last = (oldSize - 1)/SQLITE_PAGE_SIZE;
   537         -
   538         -  /* Free the direct overflow pages
   539         -  */
   540         -  if( first < N_DIRECT ){
   541         -    for(i=first; i<N_DIRECT && i<=last; i++){
   542         -      freePage(pDb, aPage[i], 0);
   543         -      aPage[i] = 0;
   544         -    }
   545         -  }
   546         -  aPage += N_DIRECT;
   547         -  first -= N_DIRECT;
   548         -  last -= N_DIRECT;
   549         -  if( last<0 ) return SQLITE_OK;
   550         -  if( first<0 ) first = 0;
   551         -  
   552         -  /* Free indirect overflow pages
   553         -  */
   554         -  if( first < U32_PER_PAGE ){
   555         -    u32 *indirPage;
   556         -    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
   557         -    if( rc!=SQLITE_OK ) return rc;
   558         -    for(i=first; i<U32_PER_PAGE && i<=last; i++){
   559         -      freePage(pDb, indirPage[i], 0);
   560         -      indirPage[i] = 0;
   561         -      touch = 1;
   562         -    }
   563         -    if( first<=0 ){
   564         -      freepage(pDb, aPage[0], indirPage);
   565         -      aPage[0] = 0;
   566         -    }else{
   567         -      sqlitePgTouch(indirPage);
   568         -      sqlitePgUnref(indirPage);
   569         -    }
   570         -  }
   571         -  aPage++;
   572         -  first -= U32_PER_PAGE;
   573         -  last -= U32_PER_PAGE;
   574         -  if( last<0 ) return SQLITE_OK;
   575         -  if( first<0 ) first = 0;
   576         -
   577         -  /* Free double-indirect overflow pages
   578         -  */
   579         -  if( first < U32_PER_PAGE*U32_PER_PAGE ){
   580         -    u32 *dblIndirPage;
   581         -    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
   582         -    if( rc!=SQLITE_OK ) return rc;
   583         -    for(i=first/U32_PER_PAGE; i<U32_PER_PAGE; i++){
   584         -      u32 *indirPage;
   585         -      basis = i*U32_PER_PAGE;
   586         -      if( last < basis ) break;
   587         -      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
   588         -      if( rc!=SQLITE_OK ) return rc;
   589         -      for(j=first>basis?first-basis:0 ; j<U32_PER_PAGE; j++){
   590         -        if( j + basis > last ) break;
   591         -        freePage(pDb, indirPage[j], 0);
   592         -        indirPage[j] = 0;
   593         -      }
   594         -      if( first<=basis ){
   595         -        freepage(pDb, dblIndirPage[i], 0);
   596         -        dblIndirPage[i] = 0;
   597         -      }else{
   598         -        sqlitePgTouch(indirPage);
   599         -        sqlitePgUnref(indirPage);
   600         -      }
   601         -    }
   602         -    if( first<=0 ){
   603         -      freepage(pDb, aPage[0], dblIndirPage);
   604         -      aPage[0] = 0;
   605         -    }else{
   606         -      sqlitePgTouch(dblIndirPage);
   607         -      sqlitePgUnref(dblIndirPage);
   608         -    }
   609         -  }
   610         -
   611         -  return SQLITE_OK;    
   612         -}
   613         -
   614         -/*
   615         -** Allocate space for the content table in the given Db structure.
   616         -** return SQLITE_OK on success and SQLITE_NOMEM if it fails.
   617         -*/
   618         -static int sqliteDbExpandTableArray(Db *pDb){
   619         -  pDb->aTable = sqliteRealloc( pDb->aTable, pDb->nTable*sizeof(u32));
   620         -  if( pDb->aTable==0 ){
   621         -    pDb->inTranaction = 0;
   622         -    return SQLITE_NOMEM;
   623         -  }
   624         -  return SQLITE_OK;
   625         -}
   626         -
   627         -/*
   628         -** Open a database.
   629         -*/
   630         -int sqliteDbOpen(const char *filename, Db **ppDb){
   631         -  Db *pDb = 0;
   632         -  Pgr *pPgr = 0;
   633         -  u32 *aPage1;
   634         -  int rc;
   635         -  u32 nPage;
   636         -
   637         -  rc = sqlitePgOpen(filename, &pPgr);
   638         -  if( rc!=SQLITE_OK ) goto open_err;
   639         -  pDb = sqliteMalloc( sizeof(*pDb) );
   640         -  if( pDb==0 ){
   641         -    rc = SQLITE_NOMEM;
   642         -    goto open_err;
   643         -  }
   644         -  pDb->pPgr = pPgr;
   645         -  pDb->pCursor = 0;
   646         -  pDb->inTransaction = 0;
   647         -  sqlitePgCount(pDb->pPgr, &nPage);
   648         -  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   649         -  if( rc!=0 ) goto open_err;
   650         -  if( nPage==0 ){
   651         -    sqlitePgBeginTransaction(pDb->pPgr);
   652         -    aPage1[0] = BLOCK_PAGE1;
   653         -    sqlitePgTouch(aPage1);
   654         -    sqlitePgCommit(pDb->pPgr);
   655         -  }
   656         -  pDb->freeList = aPage[1];
   657         -  pDb->nTable = aPage[2];
   658         -  rc = sqliteDbExpandTableArray(pDb);
   659         -  if( rc!=SQLITE_OK ) goto open_err;
   660         -  rc = payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
   661         -  sqlitePgUnref(aPage1);
   662         -  if( rc!=SQLITE_OK ) goto open_err;
   663         -  *ppDb = pDb;
   664         -  return SQLITE_OK;
   665         -
   666         -open_err:
   667         -  *ppDb = 0;
   668         -  if( pPgr ) sqlitePgClose(pPgr);
   669         -  if( pDb ){
   670         -    sqliteFree(pDb->aContent);
   671         -    sqliteFree(pDb);
   672         -  }
   673         -  return rc;
   674         -}
   675         -
   676         -/*
   677         -** Close a database
   678         -*/
   679         -int sqliteDbClose(Db *pDb){
   680         -  while( pDb->pCursor ){
   681         -    sqliteDbCursorClose(pDb->pCursor);
   682         -  }
   683         -  sqlitePgClose(pDb->pPgr);
   684         -  sqliteFree(pDb->aContent);
   685         -  sqliteFree(pDb);
   686         -  return SQLITE_OK;
   687         -}
   688         -
   689         -/*
   690         -** Begin a transaction
   691         -*/
   692         -int sqliteDbBeginTransaction(Db *pDb){
   693         -  int rc;
   694         -  if( pDb->aContent==0 ){
   695         -    return SQLITE_NOMEM;
   696         -  }
   697         -  if( pDb->inTransaction ){
   698         -    return SQLITE_INTERNAL;
   699         -  }
   700         -  rc = sqlitePgBeginTransaction(pDb->pPgr);
   701         -  if( rc!=SQLITE_OK ){
   702         -    return rc;
   703         -  }
   704         -  pDb->inTransaction = 1;
   705         -  return SQLITE_OK;
   706         -}
   707         -
   708         -/*
   709         -** Commit changes to the database
   710         -*/ 
   711         -int sqliteDbCommit(Db *pDb){
   712         -  u32 *aPage1;
   713         -  int rc;
   714         -  if( !pDb->inTransaction ){
   715         -    return SQLITE_OK;
   716         -  }
   717         -  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   718         -  if( rc!=SQLITE_OK ) return rc;
   719         -  aPage1[1] = pDb->freeList;
   720         -  aPage1[2] = pDb->nTable;
   721         -  payloadWrite(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
   722         -  sqlitePgUnref(aPage1);
   723         -  rc = sqlitePgCommit(pDb->pPgr);
   724         -  if( rc!=SQLITE_OK ) return rc;
   725         -  pDb->inTransaction = 0;
   726         -  return SQLITE_OK;
   727         -}
   728         -
   729         -/*
   730         -** Rollback the database to its state prior to the beginning of
   731         -** the transaction
   732         -*/
   733         -int sqliteDbRollback(Db *pDb){
   734         -  u32 *aPage1;
   735         -  if( !pDb->inTransaction ) return SQLITE_OK;
   736         -  rc = sqlitePgRollback(pDb->pPgr);
   737         -  if( rc!=SQLITE_OK ) return rc;
   738         -  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   739         -  if( rc!=SQLITE_OK ) return rc;
   740         -  pDb->freeList = aPage1[1];
   741         -  pDb->nTable = aPage1[2];
   742         -  if( sqliteDbExpandTableArray(pDb)!=SQLITE_OK ){
   743         -    return SQLITE_NOMEM;
   744         -  }
   745         -  payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
   746         -  sqlitePgUnref(aPage1);
   747         -  pDb->inTransaction = 0;
   748         -  return SQLITE_OK;
   749         -}
   750         -
   751         -/*
   752         -** Create a new table in the database.  Write the table number
   753         -** that is used to open a cursor into that table into *pTblno.
   754         -*/
   755         -int sqliteDbCreateTable(Db *pDb, int *pTblno){
   756         -  u32 *aPage;
   757         -  u32 pgno;
   758         -  int rc;
   759         -  int swTblno;
   760         -  int i;
   761         -
   762         -  rc = allocPage(pDb, &pgno, &aPage);
   763         -  if( rc!=SQLITE_OK ){
   764         -    return rc;
   765         -  }
   766         -  tblno = -1;
   767         -  for(i=0; i<pDb->nTable; i++){
   768         -    if( pDb->aTable[i]==0 ){
   769         -      tblno = i;
   770         -      break;
   771         -    }
   772         -  }
   773         -  if( tblno<0 ){
   774         -    pDb->nTable++;
   775         -    rc = sqliteExpandTableArray(pDb);
   776         -    if( rc!=SQLITE_OK ){
   777         -      return rc;
   778         -    }
   779         -  }
   780         -  pDb->aTable[tblno] = pgno;
   781         -  aPage[0] = BLOCK_LEAF;
   782         -  memset(&aPage[1], 0, SQLITE_PAGE_SIZE - sizeof(u32));
   783         -  sqlitePgTouch(aPage);
   784         -  sqlitePgUnref(aPage);
   785         -  return rc;
   786         -}
   787         -
   788         -/*
   789         -** Recursively add a page to the free list
   790         -*/
   791         -static int sqliteDbDropPage(Db *pDb, u32 pgno){
   792         -  u32 *aPage;
   793         -  int rc;
   794         -
   795         -  rc = sqlitePgGet(pDb->pPgr, pgno, (void**)&aPage);
   796         -  if( rc!=SQLITE_OK ) return rc;
   797         -  switch(  aPage[0] ){
   798         -    case BLOCK_INDEX: {
   799         -      int n, i;
   800         -      n = aPage[2];
   801         -      for(i=0; i<n; i++){
   802         -        u32 subpgno = aPage[3 + i*2];
   803         -        if( subpgno>0 ) sqliteDbDropPage(pDb, subpgno);
   804         -      }
   805         -      freePage(pDb, pgno, aPage);
   806         -      break;
   807         -    }
   808         -    case BLOCK_LEAF: {
   809         -      int i = 2;
   810         -      while( i<U32_PER_PAGE ){
   811         -        int entrySize = aPage[i];
   812         -        if( entrySize==0 ) break;
   813         -        payloadResize(pDb, &aPage[i+4], aPage[i+2]+aPage[i+3], 0);
   814         -        i += entrySize;
   815         -      }
   816         -      freePage(pDb, pgno, aPage);
   817         -      break;
   818         -    }
   819         -    default: {
   820         -      /* Do nothing */
   821         -      break;
   822         -    }
   823         -  }
   824         -}
   825         -
   826         -/*
   827         -** Delete the current associate of a cursor and release all the
   828         -** pages it holds.  Except, do not release pages at levels less
   829         -** than N.
   830         -*/
   831         -static void sqliteDbResetCursor(DbCursor *pCur, int N){
   832         -  int i;
   833         -  for(i=pCur->nLevel-1; i>=N; i--){
   834         -    sqlitePgUnref(pCur->aLevel[i].aPage);
   835         -  }
   836         -  pCur->nLevel = N;
   837         -  pCur->onEntry = 0;
   838         -}
   839         -
   840         -/*
   841         -** Delete an entire table.
   842         -*/
   843         -static int sqliteDbDropTable(Db *pDb, int tblno){
   844         -  DbCursor *pCur;
   845         -  u32 pgno;
   846         -
   847         -  /* Find the root page for the table to be dropped.
   848         -  */
   849         -  if( pDb->aTable==0 ){
   850         -    return SQLITE_NOMEM;
   851         -  }
   852         -  if( tblno<0 || tblno>=pDb->nTable || pDb->aTable[tblno]==0 ){
   853         -    return SQLITE_NOTFOUND;
   854         -  }
   855         -  pgno = pDb->aTable[tblno];
   856         -  pDb->aTable[tblno] = 0;
   857         -  if( tblno==pDb->nTable-1 ){
   858         -    pDb->nTable--;
   859         -  }
   860         -
   861         -  /* Reset any cursors pointing to the table that is about to
   862         -  ** be dropped */
   863         -  for(pCur=pDb->pCursor; pCur; pCur=pCur->pNext){
   864         -    if( pCur->rootPgno==pgno ){
   865         -      sqliteDbResetCursor(pCur, 0);
   866         -    }
   867         -  }
   868         -
   869         -  /* Move all pages associated with this table to the freelist
   870         -  */
   871         -  sqliteDbDropPage(pDb, pgno);
   872         -  return SQLITE_OK;
   873         -}
   874         -
   875         -/*
   876         -** Create a new cursor
   877         -*/
   878         -int sqliteDbCursorOpen(Db *pDb, int tblno, DbCursor **ppCur){
   879         -  u32 pgno;
   880         -  DbCursor *pCur;
   881         -
   882         -  /* Translate the table number into a page number
   883         -  */
   884         -  if( pDb->aTable==0 ){
   885         -    *ppCur = 0;
   886         -    return SQLITE_NOMEM;
   887         -  }
   888         -  if( tblno<0 || tblno>=pDb->nContent || pDb->aTable[tblno]==0 ){
   889         -    *ppCur = 0;
   890         -    return SQLITE_NOTFOUND;
   891         -  }
   892         -  pgno = pDb->aTable[tblno];
   893         -  
   894         -  /* Allocate the cursor
   895         -  */
   896         -  pCur = sqliteMalloc( sizeof(*pCur) );
   897         -  pCur->pgno = pgno;
   898         -  pCur->pDb = pDb;
   899         -  pCur->pNext = pDb->pCursor;
   900         -  pCur->pPrev = 0;
   901         -  if( pDb->pCursor ){
   902         -     pDb->pCursor->pPrev = pCur;
   903         -  }
   904         -  pDb->pCursor = pCur;
   905         -  *ppCur = pCur;
   906         -  return SQLITE_OK;
   907         -}
   908         -
   909         -/*
   910         -** Delete a cursor
   911         -*/
   912         -int sqliteDbCursorClose(DbCursor *pCur){
   913         -  int i;
   914         -  if( pCur->pPrev ){
   915         -    pCur->pPrev->pNext = pCur->pNext;
   916         -  }else if( pCur->pDb->pCursor==pCur ){
   917         -    pCur->pDb->pCursor = pCur->pNext;
   918         -  }
   919         -  if( pCur->pNext ){
   920         -    pCur->pNext->pPrev = pCur->pPrev;
   921         -  }
   922         -  sqliteDbResetCursor(pCur, 0);
   923         -  sqliteFree(pCur);
   924         -  return SQLITE_OK; 
   925         -}
   926         -
   927         -/*
   928         -** Beginning at index level "i" (the outer most index is 0), move down 
   929         -** to the first entry of the table.  Levels above i (less than i) are 
   930         -** unchanged.
   931         -*/
   932         -static int sqliteDbGotoFirst(DbCursor *pCur, int i){
   933         -  int rc = -1;
   934         -
   935         -  assert( i>=0 && i<MAX_LEVEL );
   936         -  if( pCur->nLevel > i+1 ){
   937         -    sqliteDbResetCursor(pCur, i+1);
   938         -  }
   939         -  assert( pCur->nLevel==i+1 );
   940         -  while( rc < 0 ){
   941         -    u32 *aPage = pCur->aLevel[i].aPage;
   942         -    assert( aPage!=0 );
   943         -    switch( aPage[0] ){
   944         -      case BLOCK_LEAF: {
   945         -        if( aPage[2]!=0 ){
   946         -          pCur->aLevel[i].idx = 2;
   947         -          pCur->onEntry = 1;
   948         -        }else{
   949         -          sqliteDbResetCursor(pCur, 1);
   950         -        }
   951         -        rc = SQLITE_OK;
   952         -        break;
   953         -      }
   954         -      case BLOCK_INDEX: {
   955         -        int n = aPage[2];
   956         -        if( n<2 || n>=((U32_PER_PAGE - 3)/2) ){
   957         -          sqliteDbResetCur(pCur, 1);
   958         -          rc = SQLITE_CORRUPT;
   959         -          break;
   960         -        }
   961         -        pCur->nLevel++;
   962         -        i++;
   963         -        pCur->aLevel[i].pgno = aPage[3];
   964         -        rc = sqlitePgGet(pCur->pDb->pPgr, pCur->aLevel[i].pgno,
   965         -                    &pCur->aLevel[i].aPage);
   966         -        if( rc != SQLITE_OK ){
   967         -          sqliteDbResetCursor(pCur, 1);
   968         -        }else{
   969         -          rc = -1;
   970         -        }
   971         -        break;
   972         -      }
   973         -      default: {
   974         -        sqliteDbResetCursor(pCur, 1);
   975         -        rc = SQLITE_CORRUPT;
   976         -      }
   977         -    }
   978         -  }
   979         -  return rc;
   980         -}
   981         -
   982         -################
   983         -
   984         -/*
   985         -** Move the cursor to the first entry in the table.
   986         -*/
   987         -int sqliteDbCursorFirst(DbCursor *pCur){
   988         -  if( pCur->nLevel==0 ){
   989         -    int rc;
   990         -    pCur->aLevel[0].pgno = pCur->rootPgno;
   991         -    rc = sqlitePgGet(pCur->pDb->pPgr, pCur->rootPgno, pCur->aLevel[0].aPage);
   992         -    if( rc!=SQLITE_OK ){
   993         -      sqliteDbResetCursor(pCur, 0);
   994         -      return rc;
   995         -    }
   996         -    pCur->nLevel = 1;
   997         -  }
   998         -  return sqliteDbGotoFirst(pCur, 0);
   999         -}
  1000         -
  1001         -/*
  1002         -** Advance the cursor to the next entry in the table.
  1003         -*/
  1004         -int sqliteDbCursorNext(DbCursor *pCur){
  1005         -  int i, idx, n, rc;
  1006         -  u32 pgno, *aPage;
  1007         -  if( !pCur->onEntry ){
  1008         -     return sqliteDbCursorFirst(pCur);
  1009         -  }
  1010         -  i = pCur->nLevel-1;
  1011         -  aPage = pCur->aLevel[i].aPage;
  1012         -  idx = pCur->aLevel[i].idx;
  1013         -  idx += SWB(aPage[idx]);
  1014         -  if( idx >= SQLITE_PAGE_SIZE/sizeof(u32) ){
  1015         -    sqliteDbResetCursor(pCur, 1);
  1016         -    return SQLITE_CORRUPT;
  1017         -  }
  1018         -  if( aPage[idx]!=0 ){
  1019         -    pCur->aLabel[i].idx = idx;
  1020         -    return SQLITE_OK;
  1021         -  }
  1022         -  rc = SQLITE_OK;
  1023         -  while( pCur->nLevel>1 ){
  1024         -    pCur->nLevel--;
  1025         -    i = pCur->nLevel-1;
  1026         -    sqlitePgUnref(pCur->aLevel[pCur->nLevel].aPage);
  1027         -    aPage = pCur->aLevel[i].aPage;
  1028         -    idx = pCur->aLevel[i].idx;
  1029         -    assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
  1030         -    n = SWB(aPage[2]);
  1031         -    idx += 2;
  1032         -    if( (idx-3)/2 < n ){
  1033         -      pCur->aLevel[i].idx = idx;
  1034         -      pCur->nLevel++;
  1035         -      i++;
  1036         -      pgno = pCur->aLevel[i].pgno = SWB(aPage[idx+1]);
  1037         -      rc = sqlitePgGet(pDb->pPgr, pgno, &pCur->aLevel[i].aPage);
  1038         -      if( rc!=SQLITE_OK ) break;
  1039         -      rc = sqliteDbGotoFirst(pCur, i);
  1040         -      break;
  1041         -    }
  1042         -  }
  1043         -  sqliteDbResetCursor(pCur, 0);
  1044         -  return SQLITE_OK;
  1045         -}
  1046         -
  1047         -/*
  1048         -** Return the amount of data on the entry that the cursor points
  1049         -** to.
  1050         -*/
  1051         -int sqliteDbCursorDatasize(DbCursor *pCur){
  1052         -  u32 *aPage;
  1053         -  int idx, i;
  1054         -  if( !pCur->onEntry ) return 0;
  1055         -  i = pCur->nLevel-1;
  1056         -  idx = pCur->aLevel[i].idx;
  1057         -  aPage = pCur->aLevel[i].aPage;
  1058         -  assert( aPage );
  1059         -  assert( idx>=2 && idx+4<U32_PER_PAGE );
  1060         -  return aPage[idx+3];
  1061         -}
  1062         -
  1063         -/*
  1064         -** Return the number of bytes of key on the entry that the cursor points
  1065         -** to.
  1066         -*/
  1067         -int sqliteDbCursorKeysize(DbCursor *pCur){
  1068         -  u32 *aPage;
  1069         -  int idx, i;
  1070         -  if( !pCur->onEntry ) return 0;
  1071         -  i = pCur->nLevel-1;
  1072         -  idx = pCur->aLevel[i].idx;
  1073         -  aPage = pCur->aLevel[i].aPage;
  1074         -  assert( aPage );
  1075         -  assert( idx>=2 && idx+4<U32_PER_PAGE );
  1076         -  return aPage[idx+2];
  1077         -}
  1078         -
  1079         -/*
  1080         -** Read data from the cursor.
  1081         -*/
  1082         -int sqliteDbCursorRead(DbCursor *pCur, int amt, int offset, void *buf){
  1083         -  u32 *aPage;
  1084         -  int idx, i;
  1085         -  int nData;
  1086         -  int nKey;
  1087         -  if( !pCur->onEntry ){
  1088         -    memset(cbuf, 0, amt);
  1089         -    return SQLITE_OK;
  1090         -  }
  1091         -  if( amt<=0 || offset<0 ){
  1092         -    return SQLITE_ERR;
  1093         -  }
  1094         -  i = pCur->nLevel-1;
  1095         -  idx = pCur->aLevel[i].idx;
  1096         -  aPage = pCur->aLevel[i].aPage;
  1097         -  assert( aPage );
  1098         -  assert( idx>=2 && idx+4<U32_PER_PAGE );
  1099         -  nData = aPage[idx+3];
  1100         -  if( offset>=nData ){
  1101         -    memset(buf, 0, amt);
  1102         -    return SQLITE_OK;
  1103         -  }
  1104         -  nKey = aPage[idx+2];
  1105         -  if( nData<offset+amt ){
  1106         -    memset(&((char*)buf)[nData-offset], 0, amt+offset-nData);
  1107         -    amt = nData - offset;
  1108         -  }
  1109         -  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset + nKey, buf);
  1110         -  return SQLITE_OK;
  1111         -}
  1112         -
  1113         -/*
  1114         -** Read the current key from the cursor.
  1115         -*/
  1116         -int sqliteDbCursorReadKey(DbCursor *pCur, int amt, int offset, void *buf){
  1117         -  u32 *aPage;
  1118         -  int idx, i;
  1119         -  int nData;
  1120         -  int nKey;
  1121         -  if( !pCur->onEntry ){
  1122         -    memset(cbuf, 0, amt);
  1123         -    return SQLITE_OK;
  1124         -  }
  1125         -  if( amt<=0 || offset<0 ){
  1126         -    return SQLITE_ERR;
  1127         -  }
  1128         -  i = pCur->nLevel-1;
  1129         -  idx = pCur->aLevel[i].idx;
  1130         -  aPage = pCur->aLevel[i].aPage;
  1131         -  assert( aPage );
  1132         -  assert( idx>=2 && idx+4<(SQLITE_PAGE_SIZE/sizeof(u32))
  1133         -  nKey = aPage[idx+2];
  1134         -  if( offset>=nKey ){
  1135         -    memset(buf, 0, amt);
  1136         -    return SQLITE_OK;
  1137         -  }
  1138         -  if( nKey<offset+amt ){
  1139         -    memset(&((char*)buf)[nKey-offset], 0, amt+offset-nKey);
  1140         -    amt = nKey - offset;
  1141         -  }
  1142         -  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset, buf);
  1143         -  return SQLITE_OK;
  1144         -}
  1145         -
  1146         -/*
  1147         -** Generate a 32-bit hash from the given key.
  1148         -*/
  1149         -static u32 sqliteDbHash(int nKey, void *pKey){
  1150         -  u32 h;
  1151         -  unsigned char *key;
  1152         -  if( nKey==4 ){
  1153         -    return *(u32*)pKey;
  1154         -  }
  1155         -  key = pKey;
  1156         -  h = 0;
  1157         -  while( 0 < nKey-- ){
  1158         -    h = (h<<13) ^ (h<<3) ^ h ^ *(key++)
  1159         -  }
  1160         -  return h;
  1161         -}
  1162         -
  1163         -/*
  1164         -** Move the cursor so that the lowest level is the leaf page that
  1165         -** contains (or might contain) the given key.
  1166         -*/
  1167         -static int sqliteDbFindLeaf(DbCursor *pCur, int nKey, void *pKey, u32 h;){
  1168         -  int i, j, rc;
  1169         -  u32 h;
  1170         -
  1171         -  h = sqliteDbHash(nKey, pKey);
  1172         -  sqliteDbResetCursor(pCur, 1);
  1173         -  i = 0;
  1174         -  for(;;){
  1175         -    u32 nxPgno;
  1176         -    u32 *aPage = pCur->aLevel[i].aPage;
  1177         -    if( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF ) break;
  1178         -    if( SWB(aPage[0])!=BLOCK_MAGIC|BLOCK_INDEX ){
  1179         -      return SQLITE_CORRUPT;
  1180         -    }
  1181         -    if( i==MAX_LEVEL-1 ){
  1182         -      return SQLITE_FULL;
  1183         -    }
  1184         -    n = SWB(aPage[2]);
  1185         -    if( n<2 || n>=(SQLITE_PAGE_SIZE/2*sizeof(u32))-2 ){
  1186         -      return SQLITE_CORRUPT;
  1187         -    }
  1188         -    for(j=0; j<n-1; j++){
  1189         -      if( h < SWB(aPage[j*2+3]) ) break;
  1190         -    }
  1191         -    nxPgno = SWB(aPage[j*2+4]);
  1192         -    pCur->aLevel[i].idx = j;
  1193         -    pCur->aLevel[i].pgno = nxPgno;
  1194         -    rc = sqlitePgGet(pCur->pDb->pPgr, nxPgno, &pCur->aLevel[i].aPage);
  1195         -    if( rc!=SQLITE_OK ){
  1196         -      return rc;
  1197         -    }
  1198         -    pCur->nLevel++;
  1199         -    i++;
  1200         -  }
  1201         -  return SQLITE_OK;
  1202         -}
  1203         -
  1204         -/*
  1205         -** Position the cursor on the entry that matches the given key.
  1206         -*/
  1207         -int sqliteDbCursorMoveTo(DbCursor *pCur, int nKey, void *pKey){
  1208         -  int rc, i;
  1209         -  u32 *aPage;
  1210         -  int idx;
  1211         -  u32 h;
  1212         -
  1213         -  h = sqliteDbHash(nKey, pKey);
  1214         -  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
  1215         -  if( rc!=SQLITE_OK ) return rc;
  1216         -  i = pCur->nLevel-1;
  1217         -  aPage = pCur->aLevel[i].aPage;
  1218         -  idx = 2;
  1219         -  rc = SQLITE_NOTFOUND;
  1220         -  while( idx>=2 && idx<(SQLITE_PAGE_SIZE/sizeof(u32))-3 && aPage[idx]!=0 ){
  1221         -    if( sqliteDbKeyMatch(&aPage[idx], nKey, pKey, h) ){
  1222         -      pCur->aLevel[i].idx = idx;
  1223         -      pCur->onEntry = 1;
  1224         -      rc = SQLITE_OK;
  1225         -      break;
  1226         -    }
  1227         -    idx += SWB(aPage[idx]);
  1228         -  }
  1229         -  return rc;
  1230         -}
  1231         -
  1232         -/*
  1233         -** Insert a new entry into the table.  The cursor is left pointing at
  1234         -** the new entry.
  1235         -*/
  1236         -int sqliteDbCursorInsert(   
  1237         -   DbCursor *pCur,          /* A cursor on the table in which to insert */
  1238         -   int nKey, void *pKey,    /* The insertion key */
  1239         -   int nData, void *pData   /* The data to be inserted */
  1240         -){
  1241         -  int minNeeded, maxNeeded;    /* In u32-sized objects */
  1242         -  int rc;
  1243         -  u32 h;
  1244         -  int available;
  1245         -  int i, j, k;
  1246         -  int nKeyU, nDataU;
  1247         -  u32 *aPage;
  1248         -  int incr = 1;
  1249         -
  1250         -  /* Null data is the same as a delete.
  1251         -  */
  1252         -  if( nData<=0 || pData==0 ){
  1253         -    if( sqliteDbCursorMoveTo(pCur, nKey, pKey);
  1254         -      return sqliteDbCursorDelete(pCur);
  1255         -    }else{
  1256         -      return SQLITE_OK;
  1257         -    }
  1258         -  }
  1259         -
  1260         -  /* Figure out how much free space is needed on a leaf block in order
  1261         -  ** to hold the new record.
  1262         -  */
  1263         -  minNeeded = maxNeeded = 6;
  1264         -  nKeyU = (nKey+3)/4;
  1265         -  nDataU = (nData+3)/4;
  1266         -  if( nKeyU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
  1267         -    maxNeeded += nKeyU;
  1268         -  }
  1269         -  if( nKeyU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
  1270         -    minNeeded += nKeyU;
  1271         -  }
  1272         -  if( nDataU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
  1273         -    maxNeeded += nDataU
  1274         -  }
  1275         -  if( nDataU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
  1276         -    minNeeded += nDataU;
  1277         -  }
  1278         -
  1279         -  /* Move the cursor to the leaf block where the new record will be
  1280         -  ** inserted.
  1281         -  */
  1282         -  h = sqliteDbHash(nKey, pKey);
  1283         -  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
  1284         -  if( rc!=SQLITE_OK ) return rc;
  1285         -
  1286         -  /* Walk thru the leaf once and do two things:
  1287         -  **   1.  Remove any prior entry with the same key.
  1288         -  **   2.  Figure out how much space is available on this leaf.
  1289         -  */
  1290         -  i = j = 2;
  1291         -  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
  1292         -  for(;;){
  1293         -    int entrySize = SWB(aPage[i]);
  1294         -    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
  1295         -    if( !sqliteDbKeyMatch(&aPage[i], nKey, pKey, h) ){
  1296         -      if( j<i ){
  1297         -        for(k=0; k<entrySize; k++){
  1298         -           aPage[j+k] = aPage[i+k];
  1299         -        }
  1300         -      }
  1301         -      j += entrySize;
  1302         -    }else{
  1303         -      sqliteDbClearEntry(pCur->pDb, &aPage[i]);
  1304         -      incr--;
  1305         -    }
  1306         -    i += entrySize;
  1307         -  }
  1308         -  available = SQLITE_PAGE_SIZE/sizeof(u32) - j;
  1309         -
  1310         -  /* If the new entry will not fit, try to move some of the entries
  1311         -  ** from this leaf onto sibling leaves.
  1312         -  */
  1313         -  if( available<minNeeded ){
  1314         -    int newSpace;
  1315         -    newSpace = sqliteDbSpreadLoad(pCur, maxNeeded); ############
  1316         -    available += newSpace;
  1317         -  }
  1318         -
  1319         -  /* If the new entry still will not fit, try to split this leaf into
  1320         -  ** two adjacent leaves.
  1321         -  */
  1322         -  if( available<minNeeded && pCur->nLevel>1 ){
  1323         -    int newAvail;
  1324         -    newAvail = sqliteDbSplit(pCur, maxNeeded); ##############
  1325         -    if( newAvail>0 ){
  1326         -      available += newAvail;
  1327         -    }
  1328         -  }
  1329         -
  1330         -  /* If the new entry does not fit after splitting, turn this leaf into
  1331         -  ** and index node with one leaf, go down into the new leaf and try 
  1332         -  ** to split again.
  1333         -  */
  1334         -  if( available<minNeeded && pCur->nLevel<MAX_LEVEL-1 ){
  1335         -    int newAvail;
  1336         -    sqliteDbNewIndexLevel(pCur);  ###############
  1337         -    newAvail = sqliteDbSplit(pCur, maxNeeded);
  1338         -    if( newAvail>0 ){
  1339         -      available = newAvail;
  1340         -    }
  1341         -  }
  1342         -
  1343         -  /* If the entry still will not fit, it means the database is full.
  1344         -  */
  1345         -  if( available<minNeeded ){
  1346         -    return SQLITE_FULL;
  1347         -  }
  1348         -
  1349         -  /* Add the new entry to the leaf block.
  1350         -  */
  1351         -  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
  1352         -  i = 2;
  1353         -  for(;;){
  1354         -    int entrySize = SWB(aPage[i]);
  1355         -    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
  1356         -    i += entrySize;
  1357         -  }
  1358         -  assert( available==SQLITE_PAGE_SIZE/sizeof(u32) - i );
  1359         -  aPage[i+1] = SWB(h);
  1360         -  available -= 5;
  1361         -  if( nKeyU <= available ){
  1362         -    aPage[i+2] = SWB(nKey);
  1363         -    memcpy(&aPage[i+4], pKey, nKey);
  1364         -    j = i + 4 + nKeyU;
  1365         -    available -= nKeyU;
  1366         -  }else{
  1367         -    u32 newPgno, *newPage;
  1368         -    aPage[i+2] = SWB(nKey | 0x80000000);
  1369         -    rc = allocPage(pCur->pDb, &newPgno, &newPage);
  1370         -    if( rc!=SQLITE_OK ) goto write_err;
  1371         -    aPage[i+4] = SWB(newPgno);
  1372         -    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
  1373         -    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nKey, pKey);
  1374         -    if( rc!=SQLITE_OK ) goto write_err;
  1375         -    j = i + 5;
  1376         -    available -= 1;
  1377         -  }
  1378         -  if( nDataU <= available ){
  1379         -    aPage[i+3] = SWB(nData);
  1380         -    memcpy(&aPage[j], pData, nData);
  1381         -    available -= nDataU;
  1382         -    j += nDataU;
  1383         -  }else{
  1384         -    u32 newPgno, *newPage;
  1385         -    aPage[i+3] = SWB(nData | 0x80000000);
  1386         -    rc = allocPage(pCur->pDb, &newPgno, &newPage);
  1387         -    if( rc!=SQLITE_OK ) goto write_err;
  1388         -    aPage[j] = SWB(newPgno);
  1389         -    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
  1390         -    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nData, pData);
  1391         -    if( rc!=SQLITE_OK ) goto write_err;
  1392         -    available -= 1;
  1393         -    j++;
  1394         -  }    
  1395         -  if( j<SQLITE_PAGE_SIZE/sizeof(u32) ){
  1396         -    aPage[j] = 0;
  1397         -  }
  1398         -  sqlitePgTouch(aPage);
  1399         -  pCur->aLevel[pCur->nLevel-1].idx = i;
  1400         -  pCur->onEntry = 1;
  1401         -
  1402         -  /*  Increment the entry count for this table.
  1403         -  */
  1404         -  if( incr!=0 ){
  1405         -    pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])+incr);
  1406         -    sqlitePgTouch(pCur->aLevel[0].aPage);
  1407         -  }
  1408         -  return SQLITE_OK;
  1409         -
  1410         -write_err:
  1411         -  aPage[i] = 0;
  1412         -  pCur->onEntry = 0;
  1413         -  return rc;
  1414         -}
  1415         -
  1416         -/*
  1417         -** Delete the entry that the cursor points to.
  1418         -*/
  1419         -int sqliteDbCursorDelete(DbCursor *pCur){
  1420         -  int i, idx;
  1421         -  int from, to, limit, n;
  1422         -  int entrySize;
  1423         -  u32 *aPage;
  1424         -  if( !pCur->onEntry ) return SQLITE_NOTFOUND;
  1425         -
  1426         -  /* Delete the entry that the cursor is pointing to.
  1427         -  */
  1428         -  i = pCur->nLevel - 1;
  1429         -  aPage = pCur->aLevel[i].aPage;
  1430         -  idx = pCur->aLevel[i].idx;
  1431         -  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF );
  1432         -  assert( idx>=2 && idx<SQLITE_PAGE_SIZE/sizeof(u32)-4 );
  1433         -  entrySize = SWB(aPage[idx]);
  1434         -  assert( entrySize>=6 && idx+entrySize<=SQLITE_PAGE_SIZE/sizeof(u32) );
  1435         -  sqliteDbClearEntry(pCur->pDb, &aPage[idx]);
  1436         -  to = idx;
  1437         -  from = idx + entrySize;
  1438         -  while( from<SQLITE_PAGE_SIZE/sizeof(u32) ){
  1439         -    int k;
  1440         -    entrySize = SWB(aPage[from]);
  1441         -    if( entrySize<=0 ) break;
  1442         -    for(k=0; k<entrySize; k++){
  1443         -      aPage[to++] = aPage[from++]
  1444         -    }
  1445         -  }
  1446         -  aPage[to] = 0;
  1447         -
  1448         -  /*  Decrement the entry count for this table.
  1449         -  */
  1450         -  pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])-1);
  1451         -  sqlitePgTouch(pCur->aLevel[0].aPage);
  1452         -
  1453         -  /* If there are more entries on this leaf or this leaf is the root
  1454         -  ** of the table,  then we are done.
  1455         -  */
  1456         -  if( to>2 || pCur->nLevel==1 ) return SQLITE_OK;
  1457         -
  1458         -  /* Collapse the tree into a more compact form.
  1459         -  */
  1460         -  sqliteDbResetCursor(pCur, pCur->nLevel-1);
  1461         -
  1462         -  i = pCur->nLevel-1;
  1463         -  assert( i>=0 && i<MAX_LEVEL );
  1464         -  idx = pCur->aLevel[i].idx;
  1465         -  aPage = pCur->aLevel[i].aPage;
  1466         -  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
  1467         -  assert( idx>=3 && idx<SQLITE_PAGE_SIZE/sizeof(u32) );
  1468         -  n = SWB(aPage[2]);
  1469         -  assert( n>=2 && n<=SQLITE_PAGE_SIZE/2*sizeof(u32)-2 );
  1470         -  sqliteDbDropPage(pCur->pDb, SWB(aPage[idx+1]);
  1471         -  to = idx;
  1472         -  from = idx+2;
  1473         -  limit = n*2 + 3;
  1474         -  while( from<limit ){
  1475         -    aPage[to++] = aPage[from++];
  1476         -  }
  1477         -  n--;
  1478         -  if( n==1 ){
  1479         -    u32 oldPgno, *oldPage;
  1480         -    oldPgno = SWB(aPage[4]);
  1481         -    rc = sqlitePgGet(pCur->pDb->pPgr, oldPgno, &oldPage);
  1482         -    if( rc!=SQLITE_OK ){
  1483         -      return rc;  /* Do something smarter here */
  1484         -    }
  1485         -    memcpy(aPage, oldPage, SQLITE_PAGE_SIZE);
  1486         -    oldPage[0] = SWB(BLOCK_MAGIC|BLOCK_OVERFLOW);
  1487         -    oldPage[1] = 0;
  1488         -    sqliteDbDropPage(pCur->pDb, oldPgno);
  1489         -    sqlitePgUnref(oldPage);
  1490         -  }else{
  1491         -    aPage[2] = SWB(n);
  1492         -  }
  1493         -  sqlitePgTouch(aPage);
  1494         -  return SQLITE_OK;
  1495         -}

Deleted src/db.h.

     1         -/*
     2         -** Copyright (c) 2001 D. Richard Hipp
     3         -**
     4         -** This program is free software; you can redistribute it and/or
     5         -** modify it under the terms of the GNU General Public
     6         -** License as published by the Free Software Foundation; either
     7         -** version 2 of the License, or (at your option) any later version.
     8         -**
     9         -** This program is distributed in the hope that it will be useful,
    10         -** but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    12         -** General Public License for more details.
    13         -** 
    14         -** You should have received a copy of the GNU General Public
    15         -** License along with this library; if not, write to the
    16         -** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    17         -** Boston, MA  02111-1307, USA.
    18         -**
    19         -** Author contact information:
    20         -**   drh@hwaci.com
    21         -**   http://www.hwaci.com/drh/
    22         -**
    23         -*************************************************************************
    24         -** $Id: db.h,v 1.5 2001/01/31 13:28:09 drh Exp $
    25         -*/
    26         -
    27         -typedef struct Db Db;
    28         -typedef struct DbCursor DbCursor;
    29         -
    30         -int sqliteDbOpen(const char *filename, Db**);
    31         -int sqliteDbClose(Db*);
    32         -int sqliteDbBeginTransaction(Db*);
    33         -int sqliteDbCommit(Db*);
    34         -int sqliteDbRollback(Db*);
    35         -
    36         -int sqliteDbCreateTable(Db*, int *pTblno);
    37         -int sqliteDbDropTable(Db*, int tblno);
    38         -
    39         -int sqliteDbCursorOpen(Db*, int tblno, DbCursor**);
    40         -int sqliteDbCursorClose(DbCursor*);
    41         -
    42         -int sqliteDbCursorFirst(DbCursor*);
    43         -int sqliteDbCursorNext(DbCursor*);
    44         -int sqliteDbCursorDatasize(DbCursor*);
    45         -int sqliteDbCursorKeysize(DbCursor*);
    46         -int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf);
    47         -int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf);
    48         -int sqliteDbCursorWrite(DbCursor*, int amt, int offset, const void *buf);
    49         -
    50         -int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createFlag);
    51         -int sqliteDbCursorResize(DbCursor*, int nData);

Added src/ex/README.

            1  +This directory is intended to hold "experimental" files.
            2  +
            3  +The code in this directory does not necessary work.  It may
            4  +or may not be added to future SQLite releases.  We just need
            5  +a place to put ideas and works-in-progress and so this 
            6  +directory was created.
            7  +
            8  +If you are interested in the production versions of SQLite,
            9  +you can safely ignore this directory.

Added src/ex/db.c.

            1  +/*
            2  +** Copyright (c) 2001 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** $Id: db.c,v 1.1 2001/02/11 16:56:24 drh Exp $
           25  +*/
           26  +#include "sqliteInt.h"
           27  +#include "pg.h"
           28  +
           29  +/*
           30  +** Everything we need to know about an open database
           31  +*/
           32  +struct Db {
           33  +  Pgr *pPgr;            /* The pager for the database */
           34  +  DbCursor *pCursor;    /* All open cursors */
           35  +  int inTransaction;    /* True if a transaction is in progress */
           36  +  u32 freeList;         /* List of free blocks */
           37  +  int nTable;           /* Number of slots in aContent[] */
           38  +  u32 *aTable;          /* Root page numbers for all tables */
           39  +};
           40  +
           41  +/*
           42  +** The maximum depth of a cursor
           43  +*/
           44  +#define MX_LEVEL 10
           45  +
           46  +/*
           47  +** Within a cursor, each level off the search tree is an instance of
           48  +** this structure.
           49  +*/
           50  +typedef struct DbIdxpt DbIdxpt;
           51  +struct DbIdxpt {
           52  +  int pgno;         /* The page number */
           53  +  u32 *aPage;       /* The page data */
           54  +  int idx;          /* Index into pPage[] */
           55  +};
           56  +
           57  +/*
           58  +** Everything we need to know about a cursor
           59  +*/
           60  +struct DbCursor {
           61  +  Db *pDb;                      /* The whole database */
           62  +  DbCursor *pPrev, *pNext;      /* Linked list of all cursors */
           63  +  u32 rootPgno;                 /* Root page of table for this cursor */
           64  +  int onEntry;                  /* True if pointing to a table entry */
           65  +  int nLevel;                   /* Number of levels of indexing used */
           66  +  DbIdxpt aLevel[MX_LEVEL];     /* The index levels */
           67  +};
           68  +
           69  +/*
           70  +** Data layouts
           71  +**
           72  +** LEAF:
           73  +**    x[0]          Magic number: BLOCK_LEAF
           74  +**    x[1]          If root page, total number of entries in this table
           75  +**    ...           One or more entries follow the leaf.
           76  +**
           77  +** Entry:
           78  +**    x[N+0]        Number of u32-sized words in this entry
           79  +**    x[N+1]        Hash value for this entry
           80  +**    x[N+2]        Number of bytes of key in the payload
           81  +**    x[N+3]        Number of bytes of data in the payload
           82  +**    x{N+4]...     The payload area.
           83  +**
           84  +** INDEX:
           85  +**    x[0]          Magic number: BLOCK_INDEX
           86  +**    x[1]          If root page: total number of entries in this table
           87  +**    x[2]          Number of slots in this index (Max value of N)
           88  +**    x[2*N+3]      Page number containing entries with hash <= x[2*N+4]
           89  +**    x[2*N+4]      The maximum hash value for entries on page x[2*N+3].
           90  +**
           91  +** FREE:
           92  +**    x[0]          Magic number: BLOCK_FREE
           93  +**    x[1]          Page number of the next free block on the free list
           94  +**
           95  +** PAGE1:
           96  +**    x[0]          Magic number: BLOCK_PAGE1
           97  +**    x[1]          First page of the freelist
           98  +**    x[2]          Number of tables in this database
           99  +**    x[N+3]        Root page for table N
          100  +
          101  +/*
          102  +** The first word of every page is some combination of these values
          103  +** used to indicate its function.
          104  +*/
          105  +#define BLOCK_PAGE1            0x24e47191
          106  +#define BLOCK_INDEX            0x7ac53b46
          107  +#define BLOCK_LEAF             0x60c45eef
          108  +#define BLOCK_FREE             0x5b2dda47
          109  +
          110  +/*
          111  +** The number of u32-sized objects that will fit on one page.
          112  +*/
          113  +#define U32_PER_PAGE  (SQLITE_PAGE_SIZE/sizeof(u32))
          114  +
          115  +/*
          116  +** Number of direct overflow pages per database entry
          117  +*/
          118  +#define N_DIRECT  10
          119  +
          120  +/*
          121  +** The maximum amount of payload (in bytes) that will fit on on the same
          122  +** page as a leaf.  In other words, the maximum amount of payload
          123  +** that does not require any overflow pages.
          124  +**
          125  +** This size is chosen so that a least 3 entry will fit on every 
          126  +** leaf.  That guarantees it will always be possible to add a new
          127  +** entry after a page split.
          128  +*/
          129  +#define LOCAL_PAYLOAD (((U32_PER_PAGE-2)/3 - (6+N_DIRECT))*sizeof(u32))
          130  +
          131  +/*
          132  +** Allocate a new page.  Return both the page number and a pointer
          133  +** to the page data.  The calling function is responsible for unref-ing
          134  +** the page when it is no longer needed.
          135  +**
          136  +** The page is obtained from the freelist if there is anything there.
          137  +** If the freelist is empty, the new page comes from the end of the
          138  +** database file.
          139  +*/
          140  +int allocPage(Db *pDb, u32 *pPgno, u32 **ppPage){
          141  +  u32 pgno;
          142  +  int rc;
          143  +
          144  +  if( pDb->aTable==0 ) return SQLITE_NOMEM;
          145  +
          146  +  /* Try to reuse a page from the freelist
          147  +  */
          148  +  if( pDb->freeList==0 ){
          149  +    u32 *pPage;
          150  +    rc = sqlitePgGet(pDb->pPgr, pDb->freeList, &pPage);
          151  +    if( rc==SQLITE_OK ){
          152  +      if( pPage[0]==BLOCK_FREE ){
          153  +        *pPgno = pDb->freeList;
          154  +        *ppPage = aPage;
          155  +        pDb->freeList = aPage[1];
          156  +        memset(*ppPage, 0, SQLITE_PAGE_SIZE);
          157  +        return SQLITE_OK;
          158  +      }
          159  +      /* This only happens if we have database corruption */
          160  +      sqlitePgUnref(pPage);
          161  +    }
          162  +  }
          163  +
          164  +  /* If the freelist is empty, or we cannot access it,
          165  +  ** then allocate a new page from the end of the file.
          166  +  */
          167  +  if( (rc = sqlitePgCount(pDb->pPgr, &pgno))==SQLITE_OK &&
          168  +      (rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage))==SQLITE_OK ){
          169  +    *pPgno = pgno;
          170  +    memset(*ppPage, 0, SQLITE_PAGE_SIZE);
          171  +    return SQLITE_OK;
          172  +  }
          173  +  return rc;
          174  +}
          175  +
          176  +/*
          177  +** Return a page to the freelist and dereference the page.
          178  +*/
          179  +static void freePage(DB *pDb, u32 pgno, u32 *aPage){
          180  +  if( pgno==0 ) return
          181  +  if( aPage==0 ){
          182  +    int rc;
          183  +    rc = sqlitePgGet(pDb->pPgr, pgno, &aPage);
          184  +    if( rc!=SQLITE_OK ) return;
          185  +  }
          186  +  assert( sqlitePgNum(aPage)==pgno );
          187  +  aPage[0] = BLOCK_FREE;
          188  +  aPage[1] = pDb->freeList;
          189  +  pDb->freeList = pgno;
          190  +  memset(&aPage[2], 0, SQLITE_PAGE_SIZE - 2*sizeof(u32));
          191  +  sqlitePgTouch(aPage);
          192  +  sqlitePgUnref(aPage);
          193  +}
          194  +
          195  +/*
          196  +** Return the number of bytes of payload storage required on the leaf
          197  +** node to hold the amount of payload specified by the argument.
          198  +** Overflow pages do not count, only memory on the leaf page.
          199  +**
          200  +** Return -1 if nTotal is more than sqlite is able to store.
          201  +*/
          202  +static int payloadLocalSize(int nTotal){
          203  +  int nLocal, i;
          204  +  if( nTotal<0 ) nTotal = 0;
          205  +  if( nTotal <= LOCAL_PAYLOAD ){
          206  +    /* All the data fits on the leaf page */
          207  +    return (nTotal + 3)/4;
          208  +  }
          209  +  nLocal = LOCAL_PAYLOAD;
          210  +  nTotal -= LOCAL_PAYLOAD;
          211  +  if( nTotal < 10*SQLITE_PAGE_SIZE ){
          212  +    return nLocal + ((nTotal+SQLITE_PAGE_SIZE-1)/SQLITE_PAGE_SIZE)*sizeof(u32);
          213  +  }
          214  +  nLocal += N_DIRECT*sizeof(u32);
          215  +  nTotal -= N_DIRECT*SQLITE_PAGE_SIZE;
          216  +  if( nTotal < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          217  +    return nLocal + sizeof(u32);
          218  +  }
          219  +  nLocal += sizeof(u32);
          220  +  nTotal -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
          221  +  if( nTotal < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          222  +    return nLocal + sizeof(u32);
          223  +  }
          224  +  return -1;  /* This payload will not fit. */
          225  +}
          226  +
          227  +/*
          228  +** Read data from the payload area.
          229  +**
          230  +** aPage points directly at the beginning of the payload.  No bounds 
          231  +** checking is done on offset or amt -- it is assumed that the payload
          232  +** area is big enough to accomodate.
          233  +*/
          234  +static int payloadRead(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
          235  +  int rc;
          236  +  int tomove;
          237  +  int i;
          238  +
          239  +  /* First read local data off of the leaf page itself.
          240  +  ** This is all that ever happens in 99% of accesses.
          241  +  */
          242  +  assert( offset>=0 && amt>=0 );
          243  +  if( offset < LOCAL_PAYLOAD ){
          244  +    /* Data stored directly in the leaf block of the BTree */
          245  +    if( amt+offset>LOCAL_PAYLOAD ){
          246  +      tomove = LOCAL_PAYLOAD - offset;
          247  +    }else{
          248  +      tomove = amt;
          249  +    }
          250  +    memcpy(pBuf, &((char*)aPage)[offset], tomove);
          251  +    pBuf = &((char*)pBuf)[tomove];
          252  +    offset += tomove;
          253  +    amt -= tomove;
          254  +    if( amt<=0 ) return SQLITE_OK;
          255  +  }
          256  +  offset -= LOCAL_PAYLOAD;
          257  +  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
          258  +
          259  +  /* If not all of the data fits locally, read from the first
          260  +  ** ten direct-access overflow pages.
          261  +  */
          262  +  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
          263  +    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
          264  +      char *aData;
          265  +      base = offset - i*SQLITE_PAGE_SIZE;
          266  +      rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
          267  +      if( rc!=SQLITE_OK ) return rc;
          268  +      if( amt+base > SQLITE_PAGE_SIZE ){
          269  +        tomove = SQLITE_PAGE_SIZE - base;
          270  +      }else{
          271  +        tomove = amt;
          272  +      }
          273  +      memcpy(pBuf, &aData[base], tomove);
          274  +      sqlitePgUnref(aData);
          275  +      pBuf = &((char*)pBuf)[tomove];
          276  +      amt -= tomove;
          277  +    }
          278  +  }
          279  +  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
          280  +  aPage += N_DIRECT;
          281  +
          282  +  /* If the first N_DIRECT overflow pages do not contain everything, then
          283  +  ** read from an overflow page that is filled with pointer to
          284  +  ** U32_PER_PAGE more overflow pages.
          285  +  */
          286  +  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          287  +    u32 *indirPage;
          288  +    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
          289  +    if( rc!=SQLITE_OK ) return rc;
          290  +    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
          291  +      int base;
          292  +      char *aData;
          293  +      base = offset - i*SQLITE_PAGE_SIZE;
          294  +      rc = sqlitePgGet(pDb->pPgr, indirPage[idx], &aData);
          295  +      if( rc!=SQLITE_OK ) break;
          296  +      if( amt+base > SQLITE_PAGE_SIZE ){
          297  +        tomove = SQLITE_PAGE_SIZE - base;
          298  +      }else{
          299  +        tomove = amt;
          300  +      }
          301  +      memcpy(pBuf, &aData[base], tomove);
          302  +      sqlitePgUnref(aData);
          303  +      pBuf = &((char*)pBuf)[tomove];
          304  +      amt -= tomove;
          305  +    }
          306  +    sqlitePgUnref(indirPage);
          307  +    if( rc!=SQLITE_OK ) return rc;
          308  +    if( amt<=0 ) return SQLITE_OK;
          309  +  }
          310  +  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
          311  +  aPage++;
          312  +
          313  +  /* If there is still more data, then read using a double-indirect
          314  +  ** overflow.  The overflow page points to U32_PER_PAGE additional
          315  +  ** overflow pages, each of which pointer to U32_PER_PAGE more overflow
          316  +  ** pages which contain data.
          317  +  **
          318  +  ** This is hard to test.  To exercise this code, you have to make
          319  +  ** a database entry of more than 273336 bytes in side, assuming a
          320  +  ** pagesize of 1024 bytes and 10 direct overflow pages.  By the 
          321  +  ** time this code runs, you have already used 267 overflow pages.
          322  +  */
          323  +  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          324  +    u32 *dblIndirPage;
          325  +    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
          326  +    if( rc!=SQLITE_OK ) return rc;
          327  +    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
          328  +    for(; i<U32_PER_PAGE && amt>0; i++){
          329  +      u32 *indirPage;
          330  +      int basis;
          331  +      int j;
          332  +      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
          333  +      if( rc!=SQLITE_OK ) break;
          334  +      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
          335  +      j = (offset - basis)/SQLITE_PAGE_SIZE;
          336  +      for(; j<U32_PER_PAGE && amt>0; j++){
          337  +        char *aData;
          338  +        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
          339  +        rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
          340  +        if( rc!=SQLITE_OK ) break;
          341  +        if( amt+base > SQLITE_PAGE_SIZE ){
          342  +          tomove = SQLITE_PAGE_SIZE - base;
          343  +        }else{
          344  +          tomove = amt;
          345  +        }
          346  +        memcpy(pBuf, &aData[base], tomove);
          347  +        sqlitePgUnref(aData);
          348  +        pBuf = &((char*)pBuf)[tomove];
          349  +        amt -= tomove;
          350  +      }
          351  +      sqlitePgUnref(indirPage);
          352  +      if( rc!=SQLITE_OK ) break;
          353  +    }
          354  +    sqlitePgUnref(dblIndirPage);
          355  +  }
          356  +
          357  +  /* Anything beyond the double-indirect pages, just fill in with
          358  +  ** zeros.  You have to write 67382200 bytes to go past the
          359  +  ** double-indirect pages, assuming a 1024 byte page size.
          360  +  */
          361  +  if( amt>0 ) memset(pBuf, 0, amt);
          362  +  return SQLITE_OK;
          363  +}
          364  +
          365  +/*
          366  +** Write data into the payload area.
          367  +**
          368  +** If pages have already been allocated for the payload, they are
          369  +** simply overwritten.  New pages are allocated as necessary to
          370  +** fill in gaps.  sqlitePgTouch() is called on all overflow pages,
          371  +** but the calling function must invoke sqlitePgTouch() for aPage
          372  +** itself.
          373  +*/
          374  +static int payloadWrite(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
          375  +  assert( offset>=0 && amt>=0 );
          376  +
          377  +  /* Local data
          378  +  */
          379  +  if( offset < LOCAL_PAYLOAD ){
          380  +    if( amt+offset>LOCAL_PAYLOAD ){
          381  +      tomove = LOCAL_PAYLOAD - offset;
          382  +    }else{
          383  +      tomove = amt;
          384  +    }
          385  +    memcpy(&((char*)aPage)[offset], pBuf, tomove);
          386  +    pBuf = &((char*)pBuf)[tomove];
          387  +    offset += tomove;
          388  +    amt -= tomove;
          389  +    if( amt<=0 ) return SQLITE_OK;
          390  +  }
          391  +  offset -= LOCAL_PAYLOAD;
          392  +  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
          393  +
          394  +  /* Direct overflow pages
          395  +  */
          396  +  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
          397  +    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
          398  +      base = offset - i*SQLITE_PAGE_SIZE;
          399  +      if( aPage[i] ){
          400  +        rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
          401  +      }else{
          402  +        rc = allocPage(pDb, &aPage[i], &aData);
          403  +      }
          404  +      if( rc!=SQLITE_OK ) return rc;
          405  +      if( amt+base > SQLITE_PAGE_SIZE ){
          406  +        tomove = SQLITE_PAGE_SIZE - base;
          407  +      }else{
          408  +        tomove = amt;
          409  +      }
          410  +      memcpy(&aData[base], pBuf, tomove);
          411  +      sqlitePgTouch(aData);
          412  +      sqlitePgUnref(aData);
          413  +      pBuf = &((char*)pBuf)[tomove];
          414  +      amt -= tomove;
          415  +    }
          416  +    if( amt<=0 ) return SQLITE_OK;
          417  +  }
          418  +  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
          419  +  aPage += N_DIRECT;
          420  +
          421  +  /* Indirect overflow pages
          422  +  */
          423  +  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          424  +    u32 *indirPage;
          425  +    if( aPage[0] ){
          426  +      rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
          427  +    }else{
          428  +      rc = allocPage(pDb, &aPage[0], &indirPage);
          429  +    }
          430  +    if( rc!=SQLITE_OK ) return rc;
          431  +    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
          432  +      int base;
          433  +      char *aData;
          434  +      base = offset - i*SQLITE_PAGE_SIZE;
          435  +      if( indirPage[i] ){
          436  +        rc = sqlitePgGet(pDb->pPgr, indirPage[i], &aData);
          437  +      }else{
          438  +        rc = allocPage(pDb, &indirPage[i], &aData);
          439  +        sqlitePgTouch(indirPage);
          440  +      }
          441  +      if( rc!=SQLITE_OK ) break;
          442  +      if( amt+base > SQLITE_PAGE_SIZE ){
          443  +        tomove = SQLITE_PAGE_SIZE - base;
          444  +      }else{
          445  +        tomove = amt;
          446  +      }
          447  +      memcpy(&aData[base], pBuf, tomove);
          448  +      sqlitePgUnref(aData);
          449  +      pBuf = &((char*)pBuf)[tomove];
          450  +      amt -= tomove;
          451  +    }
          452  +    sqlitePgUnref(indirPage);
          453  +    if( rc!=SQLITE_OK ) return rc;
          454  +    if( amt<=0 ) return SQLITE_OK;
          455  +  }
          456  +  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
          457  +  aPage++;
          458  +
          459  +  /* Double-indirect overflow pages
          460  +  */
          461  +  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
          462  +    u32 *dblIndirPage;
          463  +    if( aPage[0] ){
          464  +      rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
          465  +    }else{
          466  +      rc = allocPage(pDb, &aPage[0], &dblIndirPage);
          467  +    }
          468  +    if( rc!=SQLITE_OK ) return rc;
          469  +    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
          470  +    for(; i<U32_PER_PAGE && amt>0; i++){
          471  +      u32 *indirPage;
          472  +      int basis;
          473  +      int j;
          474  +      if( aPage[0] ){
          475  +        rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
          476  +      }else{
          477  +        rc = allocPage(pDb, &aPage[0], &dblIndirPage);
          478  +        sqlitePgTouch(dblIndirPage);
          479  +      }
          480  +      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
          481  +      if( rc!=SQLITE_OK ) break;
          482  +      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
          483  +      j = (offset - basis)/SQLITE_PAGE_SIZE;
          484  +      for(; j<U32_PER_PAGE && amt>0; j++){
          485  +        char *aData;
          486  +        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
          487  +        if( indirPage[j] ){
          488  +          rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
          489  +        }else{
          490  +          rc = allocPage(pDb, &indirPage[j], &aData);
          491  +          sqlitePgTouch(indirPage);
          492  +        }
          493  +        if( rc!=SQLITE_OK ) break;
          494  +        if( amt+base > SQLITE_PAGE_SIZE ){
          495  +          tomove = SQLITE_PAGE_SIZE - base;
          496  +        }else{
          497  +          tomove = amt;
          498  +        }
          499  +        memcpy(&aData[base], pBuf, tomove);
          500  +        sqlitePgTouch(aData);
          501  +        sqlitePgUnref(aData);
          502  +        pBuf = &((char*)pBuf)[tomove];
          503  +        amt -= tomove;
          504  +      }
          505  +      sqlitePgUnref(indirPage);
          506  +      if( rc!=SQLITE_OK ) break;
          507  +    }
          508  +    sqlitePgUnref(dblIndirPage);
          509  +  }
          510  +
          511  +  return SQLITE_OK;
          512  +}
          513  +
          514  +/*
          515  +** Resize the payload area.  If the payload area descreases in size,
          516  +** this routine deallocates unused overflow pages.  If the payload
          517  +** area increases in size, this routine is a no-op.
          518  +*/
          519  +static int payloadResize(Db *pDb, u32 *aPage, int oldSize, int newSize){
          520  +  int i, j;          /* Loop counters */
          521  +  int first, last;   /* Indices of first and last pages to be freed */
          522  +  int rc;            /* Return code from sqlitePgGet() */
          523  +
          524  +  /* Skip over the local data.  We do not need to free it.
          525  +  */
          526  +  if( newSize>=oldSize ) return SQLITE_OK;
          527  +  oldSize -= LOCAL_PAYLOAD;
          528  +  if( oldSize<=0 ) return SQLITE_OK;
          529  +  newSize -= LOCAL_PAYLOAD;
          530  +  aPage += LOCAL_PAYLOAD/sizeof(u32);
          531  +
          532  +  /* Compute the indices of the first and last overflow pages to
          533  +  ** be freed.
          534  +  */
          535  +  first = (newSize - 1)/SQLITE_PAGE_SIZE + 1;
          536  +  last = (oldSize - 1)/SQLITE_PAGE_SIZE;
          537  +
          538  +  /* Free the direct overflow pages
          539  +  */
          540  +  if( first < N_DIRECT ){
          541  +    for(i=first; i<N_DIRECT && i<=last; i++){
          542  +      freePage(pDb, aPage[i], 0);
          543  +      aPage[i] = 0;
          544  +    }
          545  +  }
          546  +  aPage += N_DIRECT;
          547  +  first -= N_DIRECT;
          548  +  last -= N_DIRECT;
          549  +  if( last<0 ) return SQLITE_OK;
          550  +  if( first<0 ) first = 0;
          551  +  
          552  +  /* Free indirect overflow pages
          553  +  */
          554  +  if( first < U32_PER_PAGE ){
          555  +    u32 *indirPage;
          556  +    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
          557  +    if( rc!=SQLITE_OK ) return rc;
          558  +    for(i=first; i<U32_PER_PAGE && i<=last; i++){
          559  +      freePage(pDb, indirPage[i], 0);
          560  +      indirPage[i] = 0;
          561  +      touch = 1;
          562  +    }
          563  +    if( first<=0 ){
          564  +      freepage(pDb, aPage[0], indirPage);
          565  +      aPage[0] = 0;
          566  +    }else{
          567  +      sqlitePgTouch(indirPage);
          568  +      sqlitePgUnref(indirPage);
          569  +    }
          570  +  }
          571  +  aPage++;
          572  +  first -= U32_PER_PAGE;
          573  +  last -= U32_PER_PAGE;
          574  +  if( last<0 ) return SQLITE_OK;
          575  +  if( first<0 ) first = 0;
          576  +
          577  +  /* Free double-indirect overflow pages
          578  +  */
          579  +  if( first < U32_PER_PAGE*U32_PER_PAGE ){
          580  +    u32 *dblIndirPage;
          581  +    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
          582  +    if( rc!=SQLITE_OK ) return rc;
          583  +    for(i=first/U32_PER_PAGE; i<U32_PER_PAGE; i++){
          584  +      u32 *indirPage;
          585  +      basis = i*U32_PER_PAGE;
          586  +      if( last < basis ) break;
          587  +      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
          588  +      if( rc!=SQLITE_OK ) return rc;
          589  +      for(j=first>basis?first-basis:0 ; j<U32_PER_PAGE; j++){
          590  +        if( j + basis > last ) break;
          591  +        freePage(pDb, indirPage[j], 0);
          592  +        indirPage[j] = 0;
          593  +      }
          594  +      if( first<=basis ){
          595  +        freepage(pDb, dblIndirPage[i], 0);
          596  +        dblIndirPage[i] = 0;
          597  +      }else{
          598  +        sqlitePgTouch(indirPage);
          599  +        sqlitePgUnref(indirPage);
          600  +      }
          601  +    }
          602  +    if( first<=0 ){
          603  +      freepage(pDb, aPage[0], dblIndirPage);
          604  +      aPage[0] = 0;
          605  +    }else{
          606  +      sqlitePgTouch(dblIndirPage);
          607  +      sqlitePgUnref(dblIndirPage);
          608  +    }
          609  +  }
          610  +
          611  +  return SQLITE_OK;    
          612  +}
          613  +
          614  +/*
          615  +** Allocate space for the content table in the given Db structure.
          616  +** return SQLITE_OK on success and SQLITE_NOMEM if it fails.
          617  +*/
          618  +static int sqliteDbExpandTableArray(Db *pDb){
          619  +  pDb->aTable = sqliteRealloc( pDb->aTable, pDb->nTable*sizeof(u32));
          620  +  if( pDb->aTable==0 ){
          621  +    pDb->inTranaction = 0;
          622  +    return SQLITE_NOMEM;
          623  +  }
          624  +  return SQLITE_OK;
          625  +}
          626  +
          627  +/*
          628  +** Open a database.
          629  +*/
          630  +int sqliteDbOpen(const char *filename, Db **ppDb){
          631  +  Db *pDb = 0;
          632  +  Pgr *pPgr = 0;
          633  +  u32 *aPage1;
          634  +  int rc;
          635  +  u32 nPage;
          636  +
          637  +  rc = sqlitePgOpen(filename, &pPgr);
          638  +  if( rc!=SQLITE_OK ) goto open_err;
          639  +  pDb = sqliteMalloc( sizeof(*pDb) );
          640  +  if( pDb==0 ){
          641  +    rc = SQLITE_NOMEM;
          642  +    goto open_err;
          643  +  }
          644  +  pDb->pPgr = pPgr;
          645  +  pDb->pCursor = 0;
          646  +  pDb->inTransaction = 0;
          647  +  sqlitePgCount(pDb->pPgr, &nPage);
          648  +  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
          649  +  if( rc!=0 ) goto open_err;
          650  +  if( nPage==0 ){
          651  +    sqlitePgBeginTransaction(pDb->pPgr);
          652  +    aPage1[0] = BLOCK_PAGE1;
          653  +    sqlitePgTouch(aPage1);
          654  +    sqlitePgCommit(pDb->pPgr);
          655  +  }
          656  +  pDb->freeList = aPage[1];
          657  +  pDb->nTable = aPage[2];
          658  +  rc = sqliteDbExpandTableArray(pDb);
          659  +  if( rc!=SQLITE_OK ) goto open_err;
          660  +  rc = payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
          661  +  sqlitePgUnref(aPage1);
          662  +  if( rc!=SQLITE_OK ) goto open_err;
          663  +  *ppDb = pDb;
          664  +  return SQLITE_OK;
          665  +
          666  +open_err:
          667  +  *ppDb = 0;
          668  +  if( pPgr ) sqlitePgClose(pPgr);
          669  +  if( pDb ){
          670  +    sqliteFree(pDb->aContent);
          671  +    sqliteFree(pDb);
          672  +  }
          673  +  return rc;
          674  +}
          675  +
          676  +/*
          677  +** Close a database
          678  +*/
          679  +int sqliteDbClose(Db *pDb){
          680  +  while( pDb->pCursor ){
          681  +    sqliteDbCursorClose(pDb->pCursor);
          682  +  }
          683  +  sqlitePgClose(pDb->pPgr);
          684  +  sqliteFree(pDb->aContent);
          685  +  sqliteFree(pDb);
          686  +  return SQLITE_OK;
          687  +}
          688  +
          689  +/*
          690  +** Begin a transaction
          691  +*/
          692  +int sqliteDbBeginTransaction(Db *pDb){
          693  +  int rc;
          694  +  if( pDb->aContent==0 ){
          695  +    return SQLITE_NOMEM;
          696  +  }
          697  +  if( pDb->inTransaction ){
          698  +    return SQLITE_INTERNAL;
          699  +  }
          700  +  rc = sqlitePgBeginTransaction(pDb->pPgr);
          701  +  if( rc!=SQLITE_OK ){
          702  +    return rc;
          703  +  }
          704  +  pDb->inTransaction = 1;
          705  +  return SQLITE_OK;
          706  +}
          707  +
          708  +/*
          709  +** Commit changes to the database
          710  +*/ 
          711  +int sqliteDbCommit(Db *pDb){
          712  +  u32 *aPage1;
          713  +  int rc;
          714  +  if( !pDb->inTransaction ){
          715  +    return SQLITE_OK;
          716  +  }
          717  +  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
          718  +  if( rc!=SQLITE_OK ) return rc;
          719  +  aPage1[1] = pDb->freeList;
          720  +  aPage1[2] = pDb->nTable;
          721  +  payloadWrite(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
          722  +  sqlitePgUnref(aPage1);
          723  +  rc = sqlitePgCommit(pDb->pPgr);
          724  +  if( rc!=SQLITE_OK ) return rc;
          725  +  pDb->inTransaction = 0;
          726  +  return SQLITE_OK;
          727  +}
          728  +
          729  +/*
          730  +** Rollback the database to its state prior to the beginning of
          731  +** the transaction
          732  +*/
          733  +int sqliteDbRollback(Db *pDb){
          734  +  u32 *aPage1;
          735  +  if( !pDb->inTransaction ) return SQLITE_OK;
          736  +  rc = sqlitePgRollback(pDb->pPgr);
          737  +  if( rc!=SQLITE_OK ) return rc;
          738  +  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
          739  +  if( rc!=SQLITE_OK ) return rc;
          740  +  pDb->freeList = aPage1[1];
          741  +  pDb->nTable = aPage1[2];
          742  +  if( sqliteDbExpandTableArray(pDb)!=SQLITE_OK ){
          743  +    return SQLITE_NOMEM;
          744  +  }
          745  +  payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
          746  +  sqlitePgUnref(aPage1);
          747  +  pDb->inTransaction = 0;
          748  +  return SQLITE_OK;
          749  +}
          750  +
          751  +/*
          752  +** Create a new table in the database.  Write the table number
          753  +** that is used to open a cursor into that table into *pTblno.
          754  +*/
          755  +int sqliteDbCreateTable(Db *pDb, int *pTblno){
          756  +  u32 *aPage;
          757  +  u32 pgno;
          758  +  int rc;
          759  +  int swTblno;
          760  +  int i;
          761  +
          762  +  rc = allocPage(pDb, &pgno, &aPage);
          763  +  if( rc!=SQLITE_OK ){
          764  +    return rc;
          765  +  }
          766  +  tblno = -1;
          767  +  for(i=0; i<pDb->nTable; i++){
          768  +    if( pDb->aTable[i]==0 ){
          769  +      tblno = i;
          770  +      break;
          771  +    }
          772  +  }
          773  +  if( tblno<0 ){
          774  +    pDb->nTable++;
          775  +    rc = sqliteExpandTableArray(pDb);
          776  +    if( rc!=SQLITE_OK ){
          777  +      return rc;
          778  +    }
          779  +  }
          780  +  pDb->aTable[tblno] = pgno;
          781  +  aPage[0] = BLOCK_LEAF;
          782  +  memset(&aPage[1], 0, SQLITE_PAGE_SIZE - sizeof(u32));
          783  +  sqlitePgTouch(aPage);
          784  +  sqlitePgUnref(aPage);
          785  +  return rc;
          786  +}
          787  +
          788  +/*
          789  +** Recursively add a page to the free list
          790  +*/
          791  +static int sqliteDbDropPage(Db *pDb, u32 pgno){
          792  +  u32 *aPage;
          793  +  int rc;
          794  +
          795  +  rc = sqlitePgGet(pDb->pPgr, pgno, (void**)&aPage);
          796  +  if( rc!=SQLITE_OK ) return rc;
          797  +  switch(  aPage[0] ){
          798  +    case BLOCK_INDEX: {
          799  +      int n, i;
          800  +      n = aPage[2];
          801  +      for(i=0; i<n; i++){
          802  +        u32 subpgno = aPage[3 + i*2];
          803  +        if( subpgno>0 ) sqliteDbDropPage(pDb, subpgno);
          804  +      }
          805  +      freePage(pDb, pgno, aPage);
          806  +      break;
          807  +    }
          808  +    case BLOCK_LEAF: {
          809  +      int i = 2;
          810  +      while( i<U32_PER_PAGE ){
          811  +        int entrySize = aPage[i];
          812  +        if( entrySize==0 ) break;
          813  +        payloadResize(pDb, &aPage[i+4], aPage[i+2]+aPage[i+3], 0);
          814  +        i += entrySize;
          815  +      }
          816  +      freePage(pDb, pgno, aPage);
          817  +      break;
          818  +    }
          819  +    default: {
          820  +      /* Do nothing */
          821  +      break;
          822  +    }
          823  +  }
          824  +}
          825  +
          826  +/*
          827  +** Delete the current associate of a cursor and release all the
          828  +** pages it holds.  Except, do not release pages at levels less
          829  +** than N.
          830  +*/
          831  +static void sqliteDbResetCursor(DbCursor *pCur, int N){
          832  +  int i;
          833  +  for(i=pCur->nLevel-1; i>=N; i--){
          834  +    sqlitePgUnref(pCur->aLevel[i].aPage);
          835  +  }
          836  +  pCur->nLevel = N;
          837  +  pCur->onEntry = 0;
          838  +}
          839  +
          840  +/*
          841  +** Delete an entire table.
          842  +*/
          843  +static int sqliteDbDropTable(Db *pDb, int tblno){
          844  +  DbCursor *pCur;
          845  +  u32 pgno;
          846  +
          847  +  /* Find the root page for the table to be dropped.
          848  +  */
          849  +  if( pDb->aTable==0 ){
          850  +    return SQLITE_NOMEM;
          851  +  }
          852  +  if( tblno<0 || tblno>=pDb->nTable || pDb->aTable[tblno]==0 ){
          853  +    return SQLITE_NOTFOUND;
          854  +  }
          855  +  pgno = pDb->aTable[tblno];
          856  +  pDb->aTable[tblno] = 0;
          857  +  if( tblno==pDb->nTable-1 ){
          858  +    pDb->nTable--;
          859  +  }
          860  +
          861  +  /* Reset any cursors pointing to the table that is about to
          862  +  ** be dropped */
          863  +  for(pCur=pDb->pCursor; pCur; pCur=pCur->pNext){
          864  +    if( pCur->rootPgno==pgno ){
          865  +      sqliteDbResetCursor(pCur, 0);
          866  +    }
          867  +  }
          868  +
          869  +  /* Move all pages associated with this table to the freelist
          870  +  */
          871  +  sqliteDbDropPage(pDb, pgno);
          872  +  return SQLITE_OK;
          873  +}
          874  +
          875  +/*
          876  +** Create a new cursor
          877  +*/
          878  +int sqliteDbCursorOpen(Db *pDb, int tblno, DbCursor **ppCur){
          879  +  u32 pgno;
          880  +  DbCursor *pCur;
          881  +
          882  +  /* Translate the table number into a page number
          883  +  */
          884  +  if( pDb->aTable==0 ){
          885  +    *ppCur = 0;
          886  +    return SQLITE_NOMEM;
          887  +  }
          888  +  if( tblno<0 || tblno>=pDb->nContent || pDb->aTable[tblno]==0 ){
          889  +    *ppCur = 0;
          890  +    return SQLITE_NOTFOUND;
          891  +  }
          892  +  pgno = pDb->aTable[tblno];
          893  +  
          894  +  /* Allocate the cursor
          895  +  */
          896  +  pCur = sqliteMalloc( sizeof(*pCur) );
          897  +  pCur->pgno = pgno;
          898  +  pCur->pDb = pDb;
          899  +  pCur->pNext = pDb->pCursor;
          900  +  pCur->pPrev = 0;
          901  +  if( pDb->pCursor ){
          902  +     pDb->pCursor->pPrev = pCur;
          903  +  }
          904  +  pDb->pCursor = pCur;
          905  +  *ppCur = pCur;
          906  +  return SQLITE_OK;
          907  +}
          908  +
          909  +/*
          910  +** Delete a cursor
          911  +*/
          912  +int sqliteDbCursorClose(DbCursor *pCur){
          913  +  int i;
          914  +  if( pCur->pPrev ){
          915  +    pCur->pPrev->pNext = pCur->pNext;
          916  +  }else if( pCur->pDb->pCursor==pCur ){
          917  +    pCur->pDb->pCursor = pCur->pNext;
          918  +  }
          919  +  if( pCur->pNext ){
          920  +    pCur->pNext->pPrev = pCur->pPrev;
          921  +  }
          922  +  sqliteDbResetCursor(pCur, 0);
          923  +  sqliteFree(pCur);
          924  +  return SQLITE_OK; 
          925  +}
          926  +
          927  +/*
          928  +** Beginning at index level "i" (the outer most index is 0), move down 
          929  +** to the first entry of the table.  Levels above i (less than i) are 
          930  +** unchanged.
          931  +*/
          932  +static int sqliteDbGotoFirst(DbCursor *pCur, int i){
          933  +  int rc = -1;
          934  +
          935  +  assert( i>=0 && i<MAX_LEVEL );
          936  +  if( pCur->nLevel > i+1 ){
          937  +    sqliteDbResetCursor(pCur, i+1);
          938  +  }
          939  +  assert( pCur->nLevel==i+1 );
          940  +  while( rc < 0 ){
          941  +    u32 *aPage = pCur->aLevel[i].aPage;
          942  +    assert( aPage!=0 );
          943  +    switch( aPage[0] ){
          944  +      case BLOCK_LEAF: {
          945  +        if( aPage[2]!=0 ){
          946  +          pCur->aLevel[i].idx = 2;
          947  +          pCur->onEntry = 1;
          948  +        }else{
          949  +          sqliteDbResetCursor(pCur, 1);
          950  +        }
          951  +        rc = SQLITE_OK;
          952  +        break;
          953  +      }
          954  +      case BLOCK_INDEX: {
          955  +        int n = aPage[2];
          956  +        if( n<2 || n>=((U32_PER_PAGE - 3)/2) ){
          957  +          sqliteDbResetCur(pCur, 1);
          958  +          rc = SQLITE_CORRUPT;
          959  +          break;
          960  +        }
          961  +        pCur->nLevel++;
          962  +        i++;
          963  +        pCur->aLevel[i].pgno = aPage[3];
          964  +        rc = sqlitePgGet(pCur->pDb->pPgr, pCur->aLevel[i].pgno,
          965  +                    &pCur->aLevel[i].aPage);
          966  +        if( rc != SQLITE_OK ){
          967  +          sqliteDbResetCursor(pCur, 1);
          968  +        }else{
          969  +          rc = -1;
          970  +        }
          971  +        break;
          972  +      }
          973  +      default: {
          974  +        sqliteDbResetCursor(pCur, 1);
          975  +        rc = SQLITE_CORRUPT;
          976  +      }
          977  +    }
          978  +  }
          979  +  return rc;
          980  +}
          981  +
          982  +################
          983  +
          984  +/*
          985  +** Move the cursor to the first entry in the table.
          986  +*/
          987  +int sqliteDbCursorFirst(DbCursor *pCur){
          988  +  if( pCur->nLevel==0 ){
          989  +    int rc;
          990  +    pCur->aLevel[0].pgno = pCur->rootPgno;
          991  +    rc = sqlitePgGet(pCur->pDb->pPgr, pCur->rootPgno, pCur->aLevel[0].aPage);
          992  +    if( rc!=SQLITE_OK ){
          993  +      sqliteDbResetCursor(pCur, 0);
          994  +      return rc;
          995  +    }
          996  +    pCur->nLevel = 1;
          997  +  }
          998  +  return sqliteDbGotoFirst(pCur, 0);
          999  +}
         1000  +
         1001  +/*
         1002  +** Advance the cursor to the next entry in the table.
         1003  +*/
         1004  +int sqliteDbCursorNext(DbCursor *pCur){
         1005  +  int i, idx, n, rc;
         1006  +  u32 pgno, *aPage;
         1007  +  if( !pCur->onEntry ){
         1008  +     return sqliteDbCursorFirst(pCur);
         1009  +  }
         1010  +  i = pCur->nLevel-1;
         1011  +  aPage = pCur->aLevel[i].aPage;
         1012  +  idx = pCur->aLevel[i].idx;
         1013  +  idx += SWB(aPage[idx]);
         1014  +  if( idx >= SQLITE_PAGE_SIZE/sizeof(u32) ){
         1015  +    sqliteDbResetCursor(pCur, 1);
         1016  +    return SQLITE_CORRUPT;
         1017  +  }
         1018  +  if( aPage[idx]!=0 ){
         1019  +    pCur->aLabel[i].idx = idx;
         1020  +    return SQLITE_OK;
         1021  +  }
         1022  +  rc = SQLITE_OK;
         1023  +  while( pCur->nLevel>1 ){
         1024  +    pCur->nLevel--;
         1025  +    i = pCur->nLevel-1;
         1026  +    sqlitePgUnref(pCur->aLevel[pCur->nLevel].aPage);
         1027  +    aPage = pCur->aLevel[i].aPage;
         1028  +    idx = pCur->aLevel[i].idx;
         1029  +    assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
         1030  +    n = SWB(aPage[2]);
         1031  +    idx += 2;
         1032  +    if( (idx-3)/2 < n ){
         1033  +      pCur->aLevel[i].idx = idx;
         1034  +      pCur->nLevel++;
         1035  +      i++;
         1036  +      pgno = pCur->aLevel[i].pgno = SWB(aPage[idx+1]);
         1037  +      rc = sqlitePgGet(pDb->pPgr, pgno, &pCur->aLevel[i].aPage);
         1038  +      if( rc!=SQLITE_OK ) break;
         1039  +      rc = sqliteDbGotoFirst(pCur, i);
         1040  +      break;
         1041  +    }
         1042  +  }
         1043  +  sqliteDbResetCursor(pCur, 0);
         1044  +  return SQLITE_OK;
         1045  +}
         1046  +
         1047  +/*
         1048  +** Return the amount of data on the entry that the cursor points
         1049  +** to.
         1050  +*/
         1051  +int sqliteDbCursorDatasize(DbCursor *pCur){
         1052  +  u32 *aPage;
         1053  +  int idx, i;
         1054  +  if( !pCur->onEntry ) return 0;
         1055  +  i = pCur->nLevel-1;
         1056  +  idx = pCur->aLevel[i].idx;
         1057  +  aPage = pCur->aLevel[i].aPage;
         1058  +  assert( aPage );
         1059  +  assert( idx>=2 && idx+4<U32_PER_PAGE );
         1060  +  return aPage[idx+3];
         1061  +}
         1062  +
         1063  +/*
         1064  +** Return the number of bytes of key on the entry that the cursor points
         1065  +** to.
         1066  +*/
         1067  +int sqliteDbCursorKeysize(DbCursor *pCur){
         1068  +  u32 *aPage;
         1069  +  int idx, i;
         1070  +  if( !pCur->onEntry ) return 0;
         1071  +  i = pCur->nLevel-1;
         1072  +  idx = pCur->aLevel[i].idx;
         1073  +  aPage = pCur->aLevel[i].aPage;
         1074  +  assert( aPage );
         1075  +  assert( idx>=2 && idx+4<U32_PER_PAGE );
         1076  +  return aPage[idx+2];
         1077  +}
         1078  +
         1079  +/*
         1080  +** Read data from the cursor.
         1081  +*/
         1082  +int sqliteDbCursorRead(DbCursor *pCur, int amt, int offset, void *buf){
         1083  +  u32 *aPage;
         1084  +  int idx, i;
         1085  +  int nData;
         1086  +  int nKey;
         1087  +  if( !pCur->onEntry ){
         1088  +    memset(cbuf, 0, amt);
         1089  +    return SQLITE_OK;
         1090  +  }
         1091  +  if( amt<=0 || offset<0 ){
         1092  +    return SQLITE_ERR;
         1093  +  }
         1094  +  i = pCur->nLevel-1;
         1095  +  idx = pCur->aLevel[i].idx;
         1096  +  aPage = pCur->aLevel[i].aPage;
         1097  +  assert( aPage );
         1098  +  assert( idx>=2 && idx+4<U32_PER_PAGE );
         1099  +  nData = aPage[idx+3];
         1100  +  if( offset>=nData ){
         1101  +    memset(buf, 0, amt);
         1102  +    return SQLITE_OK;
         1103  +  }
         1104  +  nKey = aPage[idx+2];
         1105  +  if( nData<offset+amt ){
         1106  +    memset(&((char*)buf)[nData-offset], 0, amt+offset-nData);
         1107  +    amt = nData - offset;
         1108  +  }
         1109  +  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset + nKey, buf);
         1110  +  return SQLITE_OK;
         1111  +}
         1112  +
         1113  +/*
         1114  +** Read the current key from the cursor.
         1115  +*/
         1116  +int sqliteDbCursorReadKey(DbCursor *pCur, int amt, int offset, void *buf){
         1117  +  u32 *aPage;
         1118  +  int idx, i;
         1119  +  int nData;
         1120  +  int nKey;
         1121  +  if( !pCur->onEntry ){
         1122  +    memset(cbuf, 0, amt);
         1123  +    return SQLITE_OK;
         1124  +  }
         1125  +  if( amt<=0 || offset<0 ){
         1126  +    return SQLITE_ERR;
         1127  +  }
         1128  +  i = pCur->nLevel-1;
         1129  +  idx = pCur->aLevel[i].idx;
         1130  +  aPage = pCur->aLevel[i].aPage;
         1131  +  assert( aPage );
         1132  +  assert( idx>=2 && idx+4<(SQLITE_PAGE_SIZE/sizeof(u32))
         1133  +  nKey = aPage[idx+2];
         1134  +  if( offset>=nKey ){
         1135  +    memset(buf, 0, amt);
         1136  +    return SQLITE_OK;
         1137  +  }
         1138  +  if( nKey<offset+amt ){
         1139  +    memset(&((char*)buf)[nKey-offset], 0, amt+offset-nKey);
         1140  +    amt = nKey - offset;
         1141  +  }
         1142  +  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset, buf);
         1143  +  return SQLITE_OK;
         1144  +}
         1145  +
         1146  +/*
         1147  +** Generate a 32-bit hash from the given key.
         1148  +*/
         1149  +static u32 sqliteDbHash(int nKey, void *pKey){
         1150  +  u32 h;
         1151  +  unsigned char *key;
         1152  +  if( nKey==4 ){
         1153  +    return *(u32*)pKey;
         1154  +  }
         1155  +  key = pKey;
         1156  +  h = 0;
         1157  +  while( 0 < nKey-- ){
         1158  +    h = (h<<13) ^ (h<<3) ^ h ^ *(key++)
         1159  +  }
         1160  +  return h;
         1161  +}
         1162  +
         1163  +/*
         1164  +** Move the cursor so that the lowest level is the leaf page that
         1165  +** contains (or might contain) the given key.
         1166  +*/
         1167  +static int sqliteDbFindLeaf(DbCursor *pCur, int nKey, void *pKey, u32 h;){
         1168  +  int i, j, rc;
         1169  +  u32 h;
         1170  +
         1171  +  h = sqliteDbHash(nKey, pKey);
         1172  +  sqliteDbResetCursor(pCur, 1);
         1173  +  i = 0;
         1174  +  for(;;){
         1175  +    u32 nxPgno;
         1176  +    u32 *aPage = pCur->aLevel[i].aPage;
         1177  +    if( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF ) break;
         1178  +    if( SWB(aPage[0])!=BLOCK_MAGIC|BLOCK_INDEX ){
         1179  +      return SQLITE_CORRUPT;
         1180  +    }
         1181  +    if( i==MAX_LEVEL-1 ){
         1182  +      return SQLITE_FULL;
         1183  +    }
         1184  +    n = SWB(aPage[2]);
         1185  +    if( n<2 || n>=(SQLITE_PAGE_SIZE/2*sizeof(u32))-2 ){
         1186  +      return SQLITE_CORRUPT;
         1187  +    }
         1188  +    for(j=0; j<n-1; j++){
         1189  +      if( h < SWB(aPage[j*2+3]) ) break;
         1190  +    }
         1191  +    nxPgno = SWB(aPage[j*2+4]);
         1192  +    pCur->aLevel[i].idx = j;
         1193  +    pCur->aLevel[i].pgno = nxPgno;
         1194  +    rc = sqlitePgGet(pCur->pDb->pPgr, nxPgno, &pCur->aLevel[i].aPage);
         1195  +    if( rc!=SQLITE_OK ){
         1196  +      return rc;
         1197  +    }
         1198  +    pCur->nLevel++;
         1199  +    i++;
         1200  +  }
         1201  +  return SQLITE_OK;
         1202  +}
         1203  +
         1204  +/*
         1205  +** Position the cursor on the entry that matches the given key.
         1206  +*/
         1207  +int sqliteDbCursorMoveTo(DbCursor *pCur, int nKey, void *pKey){
         1208  +  int rc, i;
         1209  +  u32 *aPage;
         1210  +  int idx;
         1211  +  u32 h;
         1212  +
         1213  +  h = sqliteDbHash(nKey, pKey);
         1214  +  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
         1215  +  if( rc!=SQLITE_OK ) return rc;
         1216  +  i = pCur->nLevel-1;
         1217  +  aPage = pCur->aLevel[i].aPage;
         1218  +  idx = 2;
         1219  +  rc = SQLITE_NOTFOUND;
         1220  +  while( idx>=2 && idx<(SQLITE_PAGE_SIZE/sizeof(u32))-3 && aPage[idx]!=0 ){
         1221  +    if( sqliteDbKeyMatch(&aPage[idx], nKey, pKey, h) ){
         1222  +      pCur->aLevel[i].idx = idx;
         1223  +      pCur->onEntry = 1;
         1224  +      rc = SQLITE_OK;
         1225  +      break;
         1226  +    }
         1227  +    idx += SWB(aPage[idx]);
         1228  +  }
         1229  +  return rc;
         1230  +}
         1231  +
         1232  +/*
         1233  +** Insert a new entry into the table.  The cursor is left pointing at
         1234  +** the new entry.
         1235  +*/
         1236  +int sqliteDbCursorInsert(   
         1237  +   DbCursor *pCur,          /* A cursor on the table in which to insert */
         1238  +   int nKey, void *pKey,    /* The insertion key */
         1239  +   int nData, void *pData   /* The data to be inserted */
         1240  +){
         1241  +  int minNeeded, maxNeeded;    /* In u32-sized objects */
         1242  +  int rc;
         1243  +  u32 h;
         1244  +  int available;
         1245  +  int i, j, k;
         1246  +  int nKeyU, nDataU;
         1247  +  u32 *aPage;
         1248  +  int incr = 1;
         1249  +
         1250  +  /* Null data is the same as a delete.
         1251  +  */
         1252  +  if( nData<=0 || pData==0 ){
         1253  +    if( sqliteDbCursorMoveTo(pCur, nKey, pKey);
         1254  +      return sqliteDbCursorDelete(pCur);
         1255  +    }else{
         1256  +      return SQLITE_OK;
         1257  +    }
         1258  +  }
         1259  +
         1260  +  /* Figure out how much free space is needed on a leaf block in order
         1261  +  ** to hold the new record.
         1262  +  */
         1263  +  minNeeded = maxNeeded = 6;
         1264  +  nKeyU = (nKey+3)/4;
         1265  +  nDataU = (nData+3)/4;
         1266  +  if( nKeyU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
         1267  +    maxNeeded += nKeyU;
         1268  +  }
         1269  +  if( nKeyU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
         1270  +    minNeeded += nKeyU;
         1271  +  }
         1272  +  if( nDataU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
         1273  +    maxNeeded += nDataU
         1274  +  }
         1275  +  if( nDataU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
         1276  +    minNeeded += nDataU;
         1277  +  }
         1278  +
         1279  +  /* Move the cursor to the leaf block where the new record will be
         1280  +  ** inserted.
         1281  +  */
         1282  +  h = sqliteDbHash(nKey, pKey);
         1283  +  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
         1284  +  if( rc!=SQLITE_OK ) return rc;
         1285  +
         1286  +  /* Walk thru the leaf once and do two things:
         1287  +  **   1.  Remove any prior entry with the same key.
         1288  +  **   2.  Figure out how much space is available on this leaf.
         1289  +  */
         1290  +  i = j = 2;
         1291  +  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
         1292  +  for(;;){
         1293  +    int entrySize = SWB(aPage[i]);
         1294  +    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
         1295  +    if( !sqliteDbKeyMatch(&aPage[i], nKey, pKey, h) ){
         1296  +      if( j<i ){
         1297  +        for(k=0; k<entrySize; k++){
         1298  +           aPage[j+k] = aPage[i+k];
         1299  +        }
         1300  +      }
         1301  +      j += entrySize;
         1302  +    }else{
         1303  +      sqliteDbClearEntry(pCur->pDb, &aPage[i]);
         1304  +      incr--;
         1305  +    }
         1306  +    i += entrySize;
         1307  +  }
         1308  +  available = SQLITE_PAGE_SIZE/sizeof(u32) - j;
         1309  +
         1310  +  /* If the new entry will not fit, try to move some of the entries
         1311  +  ** from this leaf onto sibling leaves.
         1312  +  */
         1313  +  if( available<minNeeded ){
         1314  +    int newSpace;
         1315  +    newSpace = sqliteDbSpreadLoad(pCur, maxNeeded); ############
         1316  +    available += newSpace;
         1317  +  }
         1318  +
         1319  +  /* If the new entry still will not fit, try to split this leaf into
         1320  +  ** two adjacent leaves.
         1321  +  */
         1322  +  if( available<minNeeded && pCur->nLevel>1 ){
         1323  +    int newAvail;
         1324  +    newAvail = sqliteDbSplit(pCur, maxNeeded); ##############
         1325  +    if( newAvail>0 ){
         1326  +      available += newAvail;
         1327  +    }
         1328  +  }
         1329  +
         1330  +  /* If the new entry does not fit after splitting, turn this leaf into
         1331  +  ** and index node with one leaf, go down into the new leaf and try 
         1332  +  ** to split again.
         1333  +  */
         1334  +  if( available<minNeeded && pCur->nLevel<MAX_LEVEL-1 ){
         1335  +    int newAvail;
         1336  +    sqliteDbNewIndexLevel(pCur);  ###############
         1337  +    newAvail = sqliteDbSplit(pCur, maxNeeded);
         1338  +    if( newAvail>0 ){
         1339  +      available = newAvail;
         1340  +    }
         1341  +  }
         1342  +
         1343  +  /* If the entry still will not fit, it means the database is full.
         1344  +  */
         1345  +  if( available<minNeeded ){
         1346  +    return SQLITE_FULL;
         1347  +  }
         1348  +
         1349  +  /* Add the new entry to the leaf block.
         1350  +  */
         1351  +  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
         1352  +  i = 2;
         1353  +  for(;;){
         1354  +    int entrySize = SWB(aPage[i]);
         1355  +    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
         1356  +    i += entrySize;
         1357  +  }
         1358  +  assert( available==SQLITE_PAGE_SIZE/sizeof(u32) - i );
         1359  +  aPage[i+1] = SWB(h);
         1360  +  available -= 5;
         1361  +  if( nKeyU <= available ){
         1362  +    aPage[i+2] = SWB(nKey);
         1363  +    memcpy(&aPage[i+4], pKey, nKey);
         1364  +    j = i + 4 + nKeyU;
         1365  +    available -= nKeyU;
         1366  +  }else{
         1367  +    u32 newPgno, *newPage;
         1368  +    aPage[i+2] = SWB(nKey | 0x80000000);
         1369  +    rc = allocPage(pCur->pDb, &newPgno, &newPage);
         1370  +    if( rc!=SQLITE_OK ) goto write_err;
         1371  +    aPage[i+4] = SWB(newPgno);
         1372  +    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
         1373  +    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nKey, pKey);
         1374  +    if( rc!=SQLITE_OK ) goto write_err;
         1375  +    j = i + 5;
         1376  +    available -= 1;
         1377  +  }
         1378  +  if( nDataU <= available ){
         1379  +    aPage[i+3] = SWB(nData);
         1380  +    memcpy(&aPage[j], pData, nData);
         1381  +    available -= nDataU;
         1382  +    j += nDataU;
         1383  +  }else{
         1384  +    u32 newPgno, *newPage;
         1385  +    aPage[i+3] = SWB(nData | 0x80000000);
         1386  +    rc = allocPage(pCur->pDb, &newPgno, &newPage);
         1387  +    if( rc!=SQLITE_OK ) goto write_err;
         1388  +    aPage[j] = SWB(newPgno);
         1389  +    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
         1390  +    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nData, pData);
         1391  +    if( rc!=SQLITE_OK ) goto write_err;
         1392  +    available -= 1;
         1393  +    j++;
         1394  +  }    
         1395  +  if( j<SQLITE_PAGE_SIZE/sizeof(u32) ){
         1396  +    aPage[j] = 0;
         1397  +  }
         1398  +  sqlitePgTouch(aPage);
         1399  +  pCur->aLevel[pCur->nLevel-1].idx = i;
         1400  +  pCur->onEntry = 1;
         1401  +
         1402  +  /*  Increment the entry count for this table.
         1403  +  */
         1404  +  if( incr!=0 ){
         1405  +    pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])+incr);
         1406  +    sqlitePgTouch(pCur->aLevel[0].aPage);
         1407  +  }
         1408  +  return SQLITE_OK;
         1409  +
         1410  +write_err:
         1411  +  aPage[i] = 0;
         1412  +  pCur->onEntry = 0;
         1413  +  return rc;
         1414  +}
         1415  +
         1416  +/*
         1417  +** Delete the entry that the cursor points to.
         1418  +*/
         1419  +int sqliteDbCursorDelete(DbCursor *pCur){
         1420  +  int i, idx;
         1421  +  int from, to, limit, n;
         1422  +  int entrySize;
         1423  +  u32 *aPage;
         1424  +  if( !pCur->onEntry ) return SQLITE_NOTFOUND;
         1425  +
         1426  +  /* Delete the entry that the cursor is pointing to.
         1427  +  */
         1428  +  i = pCur->nLevel - 1;
         1429  +  aPage = pCur->aLevel[i].aPage;
         1430  +  idx = pCur->aLevel[i].idx;
         1431  +  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF );
         1432  +  assert( idx>=2 && idx<SQLITE_PAGE_SIZE/sizeof(u32)-4 );
         1433  +  entrySize = SWB(aPage[idx]);
         1434  +  assert( entrySize>=6 && idx+entrySize<=SQLITE_PAGE_SIZE/sizeof(u32) );
         1435  +  sqliteDbClearEntry(pCur->pDb, &aPage[idx]);
         1436  +  to = idx;
         1437  +  from = idx + entrySize;
         1438  +  while( from<SQLITE_PAGE_SIZE/sizeof(u32) ){
         1439  +    int k;
         1440  +    entrySize = SWB(aPage[from]);
         1441  +    if( entrySize<=0 ) break;
         1442  +    for(k=0; k<entrySize; k++){
         1443  +      aPage[to++] = aPage[from++]
         1444  +    }
         1445  +  }
         1446  +  aPage[to] = 0;
         1447  +
         1448  +  /*  Decrement the entry count for this table.
         1449  +  */
         1450  +  pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])-1);
         1451  +  sqlitePgTouch(pCur->aLevel[0].aPage);
         1452  +
         1453  +  /* If there are more entries on this leaf or this leaf is the root
         1454  +  ** of the table,  then we are done.
         1455  +  */
         1456  +  if( to>2 || pCur->nLevel==1 ) return SQLITE_OK;
         1457  +
         1458  +  /* Collapse the tree into a more compact form.
         1459  +  */
         1460  +  sqliteDbResetCursor(pCur, pCur->nLevel-1);
         1461  +
         1462  +  i = pCur->nLevel-1;
         1463  +  assert( i>=0 && i<MAX_LEVEL );
         1464  +  idx = pCur->aLevel[i].idx;
         1465  +  aPage = pCur->aLevel[i].aPage;
         1466  +  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
         1467  +  assert( idx>=3 && idx<SQLITE_PAGE_SIZE/sizeof(u32) );
         1468  +  n = SWB(aPage[2]);
         1469  +  assert( n>=2 && n<=SQLITE_PAGE_SIZE/2*sizeof(u32)-2 );
         1470  +  sqliteDbDropPage(pCur->pDb, SWB(aPage[idx+1]);
         1471  +  to = idx;
         1472  +  from = idx+2;
         1473  +  limit = n*2 + 3;
         1474  +  while( from<limit ){
         1475  +    aPage[to++] = aPage[from++];
         1476  +  }
         1477  +  n--;
         1478  +  if( n==1 ){
         1479  +    u32 oldPgno, *oldPage;
         1480  +    oldPgno = SWB(aPage[4]);
         1481  +    rc = sqlitePgGet(pCur->pDb->pPgr, oldPgno, &oldPage);
         1482  +    if( rc!=SQLITE_OK ){
         1483  +      return rc;  /* Do something smarter here */
         1484  +    }
         1485  +    memcpy(aPage, oldPage, SQLITE_PAGE_SIZE);
         1486  +    oldPage[0] = SWB(BLOCK_MAGIC|BLOCK_OVERFLOW);
         1487  +    oldPage[1] = 0;
         1488  +    sqliteDbDropPage(pCur->pDb, oldPgno);
         1489  +    sqlitePgUnref(oldPage);
         1490  +  }else{
         1491  +    aPage[2] = SWB(n);
         1492  +  }
         1493  +  sqlitePgTouch(aPage);
         1494  +  return SQLITE_OK;
         1495  +}

Added src/ex/db.h.

            1  +/*
            2  +** Copyright (c) 2001 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** $Id: db.h,v 1.1 2001/02/11 16:56:24 drh Exp $
           25  +*/
           26  +
           27  +typedef struct Db Db;
           28  +typedef struct DbCursor DbCursor;
           29  +
           30  +int sqliteDbOpen(const char *filename, Db**);
           31  +int sqliteDbClose(Db*);
           32  +int sqliteDbBeginTransaction(Db*);
           33  +int sqliteDbCommit(Db*);
           34  +int sqliteDbRollback(Db*);
           35  +
           36  +int sqliteDbCreateTable(Db*, int *pTblno);
           37  +int sqliteDbDropTable(Db*, int tblno);
           38  +
           39  +int sqliteDbCursorOpen(Db*, int tblno, DbCursor**);
           40  +int sqliteDbCursorClose(DbCursor*);
           41  +
           42  +int sqliteDbCursorFirst(DbCursor*);
           43  +int sqliteDbCursorNext(DbCursor*);
           44  +int sqliteDbCursorDatasize(DbCursor*);
           45  +int sqliteDbCursorKeysize(DbCursor*);
           46  +int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf);
           47  +int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf);
           48  +int sqliteDbCursorWrite(DbCursor*, int amt, int offset, const void *buf);
           49  +
           50  +int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createFlag);
           51  +int sqliteDbCursorResize(DbCursor*, int nData);

Added src/ex/dbbebdb1.c.

            1  +/*
            2  +** Copyright (c) 2000 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** This file contains code to implement the database backend (DBBE)
           25  +** for sqlite.  The database backend is the interface between
           26  +** sqlite and the code that does the actually reading and writing
           27  +** of information to the disk.
           28  +**
           29  +** This file uses Berkeley Database version 1.85 as the database backend.
           30  +**
           31  +** $Id: dbbebdb1.c,v 1.1 2001/02/11 16:56:24 drh Exp $
           32  +*/
           33  +#ifdef USE_BDB2
           34  +
           35  +#include "sqliteInt.h"
           36  +#include <sys/types.h>
           37  +#include <limits.h>
           38  +#include <db.h>
           39  +#include <sys/stat.h>
           40  +#include <unistd.h>
           41  +#include <ctype.h>
           42  +#include <time.h>
           43  +
           44  +/*
           45  +** Information about each open disk file is an instance of this 
           46  +** structure.  There will only be one such structure for each
           47  +** disk file.  If the VDBE opens the same file twice (as will happen
           48  +** for a self-join, for example) then two DbbeCursor structures are
           49  +** created but there is only a single BeFile structure with an
           50  +** nRef of 2.
           51  +*/
           52  +typedef struct BeFile BeFile;
           53  +struct BeFile {
           54  +  char *zName;            /* Name of the file */
           55  +  DB dbf;                 /* The file itself */
           56  +  int nRef;               /* Number of references */
           57  +  int delOnClose;         /* Delete when closing */
           58  +  int writeable;          /* Opened for writing */
           59  +  DbbeCursor *pCursor; /* Which of several DbbeCursors has the file cursor */
           60  +  BeFile *pNext, *pPrev;  /* Next and previous on list of open files */
           61  +};
           62  +
           63  +/*
           64  +** The following structure contains all information used by BDB2
           65  +** database driver.  This is a subclass of the Dbbe structure.
           66  +*/
           67  +typedef struct Dbbex Dbbex;
           68  +struct Dbbex {
           69  +  Dbbe dbbe;         /* The base class */
           70  +  int write;         /* True for write permission */
           71  +  BeFile *pOpen;     /* List of open files */
           72  +  char *zDir;        /* Directory hold the database */
           73  +};
           74  +
           75  +/*
           76  +** An cursor into a database file is an instance of the following structure.
           77  +** There can only be a single BeFile structure for each disk file, but
           78  +** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
           79  +** a cursor pointing to a particular part of the open BeFile.  The
           80  +** BeFile.nRef field hold a count of the number of DbbeCursor structures
           81  +** associated with the same disk file.
           82  +*/
           83  +struct DbbeCursor {
           84  +  Dbbex *pBe;        /* The database of which this record is a part */
           85  +  BeFile *pFile;     /* The database file for this table */
           86  +  DBT key;           /* Most recently used key */
           87  +  DBT data;          /* Most recent data */
           88  +  int needRewind;    /* Next key should be the first */
           89  +  int readPending;   /* The fetch hasn't actually been done yet */
           90  +};
           91  +
           92  +/*
           93  +** The "mkdir()" function only takes one argument under Windows.
           94  +*/
           95  +#if OS_WIN
           96  +# define mkdir(A,B) mkdir(A)
           97  +#endif
           98  +
           99  +/*
          100  +** Forward declaration
          101  +*/
          102  +static void sqliteBdb1CloseCursor(DbbeCursor *pCursr);
          103  +
          104  +/*
          105  +** Completely shutdown the given database.  Close all files.  Free all memory.
          106  +*/
          107  +static void sqliteBdb1Close(Dbbe *pDbbe){
          108  +  Dbbex *pBe = (Dbbex*)pDbbe;
          109  +  BeFile *pFile, *pNext;
          110  +  for(pFile=pBe->pOpen; pFile; pFile=pNext){
          111  +    pNext = pFile->pNext;
          112  +    (*pFile->dbf)(pFile->dbf);
          113  +    memset(pFile, 0, sizeof(*pFile));   
          114  +    sqliteFree(pFile);
          115  +  }
          116  +  sqliteDbbeCloseAllTempFiles(pDbbe);
          117  +  memset(pBe, 0, sizeof(*pBe));
          118  +  sqliteFree(pBe);
          119  +}
          120  +
          121  +/*
          122  +** Translate the name of an SQL table (or index) into the name 
          123  +** of a file that holds the key/data pairs for that table or
          124  +** index.  Space to hold the filename is obtained from
          125  +** sqliteMalloc() and must be freed by the calling function.
          126  +*/
          127  +static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
          128  +  return sqliteDbbeNameToFile(pBe->zDir, zTable, ".tbl");
          129  +}
          130  +
          131  +/*
          132  +** Open a new table cursor.  Write a pointer to the corresponding
          133  +** DbbeCursor structure into *ppCursr.  Return an integer success
          134  +** code:
          135  +**
          136  +**    SQLITE_OK          It worked!
          137  +**
          138  +**    SQLITE_NOMEM       sqliteMalloc() failed
          139  +**
          140  +**    SQLITE_PERM        Attempt to access a file for which file
          141  +**                       access permission is denied
          142  +**
          143  +**    SQLITE_BUSY        Another thread or process is already using
          144  +**                       the corresponding file and has that file locked.
          145  +**
          146  +**    SQLITE_READONLY    The current thread already has this file open
          147  +**                       readonly but you are trying to open for writing.
          148  +**                       (This can happen if a SELECT callback tries to
          149  +**                       do an UPDATE or DELETE.)
          150  +**
          151  +** If zTable is 0 or "", then a temporary database file is created and
          152  +** a cursor to that temporary file is opened.  The temporary file
          153  +** will be deleted from the disk when it is closed.
          154  +*/
          155  +static int sqliteBdb1OpenCursor(
          156  +  Dbbe *pDbbe,            /* The database the table belongs to */
          157  +  const char *zTable,     /* The SQL name of the file to be opened */
          158  +  int writeable,          /* True to open for writing */
          159  +  int intKeyOnly,         /* True if only integer keys are used */
          160  +  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
          161  +){
          162  +  char *zFile;            /* Name of the table file */
          163  +  DbbeCursor *pCursr;     /* The new table cursor */
          164  +  BeFile *pFile;          /* The underlying data file for this table */
          165  +  int rc = SQLITE_OK;     /* Return value */
          166  +  int open_flags;         /* Flags passed to dbopen() */
          167  +  Dbbex *pBe = (Dbbex*)pDbbe;
          168  +
          169  +  *ppCursr = 0;
          170  +  pCursr = sqliteMalloc( sizeof(*pCursr) );
          171  +  if( pCursr==0 ) return SQLITE_NOMEM;
          172  +  if( zTable ){
          173  +    zFile = sqliteFileOfTable(pBe, zTable);
          174  +    for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
          175  +      if( strcmp(pFile->zName,zFile)==0 ) break;
          176  +    }
          177  +  }else{
          178  +    pFile = 0;
          179  +    zFile = 0;
          180  +  }
          181  +  if( pFile==0 ){
          182  +    if( writeable ){
          183  +      open_flags = O_RDWR|O_CREAT
          184  +    }else{
          185  +      open_flags = O_RDONLY;
          186  +    }
          187  +    pFile = sqliteMalloc( sizeof(*pFile) );
          188  +    if( pFile==0 ){
          189  +      sqliteFree(zFile);
          190  +      return SQLITE_NOMEM;
          191  +    }
          192  +    if( zFile ){
          193  +      if( !writeable || pBe->write ){
          194  +        pFile->dbf = dbopen(zFile, open_flags, DB_HASH, 0);
          195  +      }else{
          196  +        pFile->dbf = 0;
          197  +      }
          198  +    }else{
          199  +      int limit;
          200  +      char zRandom[50];
          201  +      zFile = 0;
          202  +      limit = 5;
          203  +      do {
          204  +        sqliteRandomName(zRandom, "_temp_table_");
          205  +        sqliteFree(zFile);
          206  +        zFile = sqliteFileOfTable(pBe, zRandom);
          207  +        pFile->dbf = dbopen(zFile, open_flags, DB_HASH, 0);
          208  +      }while( pFile->dbf==0 && limit-- >= 0);
          209  +      pFile->delOnClose = 1;
          210  +    }
          211  +    pFile->writeable = writeable;
          212  +    pFile->zName = zFile;
          213  +    pFile->nRef = 1;
          214  +    pFile->pPrev = 0;
          215  +    if( pBe->pOpen ){
          216  +      pBe->pOpen->pPrev = pFile;
          217  +    }
          218  +    pFile->pCursor = 0;
          219  +    pFile->pNext = pBe->pOpen;
          220  +    pBe->pOpen = pFile;
          221  +    if( pFile->dbf==0 ){
          222  +      if( !writeable && access(zFile,0) ){
          223  +        /* Trying to read a non-existant file.  This is OK.  All the
          224  +        ** reads will return empty, which is what we want. */
          225  +        rc = SQLITE_OK;   
          226  +      }else if( pBe->write==0 ){
          227  +        rc = SQLITE_READONLY;
          228  +      }else if( access(zFile,W_OK|R_OK) ){
          229  +        rc = SQLITE_PERM;
          230  +      }else{
          231  +        rc = SQLITE_BUSY;
          232  +      }
          233  +    }
          234  +  }else{
          235  +    sqliteFree(zFile);
          236  +    pFile->nRef++;
          237  +    if( writeable && !pFile->writeable ){
          238  +      rc = SQLITE_READONLY;
          239  +    }
          240  +  }
          241  +  pCursr->pBe = pBe;
          242  +  pCursr->pFile = pFile;
          243  +  pCursr->readPending = 0;
          244  +  pCursr->needRewind = 1;
          245  +  if( rc!=SQLITE_OK ){
          246  +    sqliteBdb1CloseCursor(pCursr);
          247  +    *ppCursr = 0;
          248  +  }else{
          249  +    *ppCursr = pCursr;
          250  +  }
          251  +  return rc;
          252  +}
          253  +
          254  +/*
          255  +** Drop a table from the database.  The file on the disk that corresponds
          256  +** to this table is deleted.
          257  +*/
          258  +static void sqliteBdb1DropTable(Dbbe *pBe, const char *zTable){
          259  +  char *zFile;            /* Name of the table file */
          260  +
          261  +  zFile = sqliteFileOfTable((Dbbex*)pBe, zTable);
          262  +  unlink(zFile);
          263  +  sqliteFree(zFile);
          264  +}
          265  +
          266  +/*
          267  +** Close a cursor previously opened by sqliteBdb1OpenCursor().
          268  +**
          269  +** There can be multiple cursors pointing to the same open file.
          270  +** The underlying file is not closed until all cursors have been
          271  +** closed.  This routine decrements the BeFile.nref field of the
          272  +** underlying file and closes the file when nref reaches 0.
          273  +*/
          274  +static void sqliteBdb1CloseCursor(DbbeCursor *pCursr){
          275  +  BeFile *pFile;
          276  +  Dbbex *pBe;
          277  +  if( pCursr==0 ) return;
          278  +  pFile = pCursr->pFile;
          279  +  pBe = pCursr->pBe;
          280  +  if( pFile->pCursor==pCursr ){
          281  +    pFile->pCursor = 0;
          282  +  }
          283  +  pFile->nRef--;
          284  +  if( pFile->dbf!=NULL ){
          285  +    (*pFile->dbf->sync)(pFile->dbf, 0);
          286  +  }
          287  +  if( pFile->nRef<=0 ){
          288  +    if( pFile->dbf!=NULL ){
          289  +      (*pFile->dbf->close)(pFile->dbf);
          290  +    }
          291  +    if( pFile->pPrev ){
          292  +      pFile->pPrev->pNext = pFile->pNext;
          293  +    }else{
          294  +      pBe->pOpen = pFile->pNext;
          295  +    }
          296  +    if( pFile->pNext ){
          297  +      pFile->pNext->pPrev = pFile->pPrev;
          298  +    }
          299  +    if( pFile->delOnClose ){
          300  +      unlink(pFile->zName);
          301  +    }
          302  +    sqliteFree(pFile->zName);
          303  +    memset(pFile, 0, sizeof(*pFile));
          304  +    sqliteFree(pFile);
          305  +  }
          306  +  if( pCursr->key.dptr ) free(pCursr->key.dptr); ######
          307  +  if( pCursr->data.dptr ) free(pCursr->data.dptr); ######
          308  +  memset(pCursr, 0, sizeof(*pCursr));
          309  +  sqliteFree(pCursr);
          310  +}
          311  +
          312  +/*
          313  +** Reorganize a table to reduce search times and disk usage.
          314  +*/
          315  +static int sqliteBdb1ReorganizeTable(Dbbe *pBe, const char *zTable){
          316  +  /* No-op */
          317  +  return SQLITE_OK;
          318  +}
          319  +
          320  +/*
          321  +** Clear the given datum
          322  +*/
          323  +static void datumClear(datum *p){
          324  +  if( p->dptr ) free(p->dptr); ########
          325  +  p->data = 0;
          326  +  p->size = 0;
          327  +}
          328  +
          329  +/*
          330  +** Fetch a single record from an open cursor.  Return 1 on success
          331  +** and 0 on failure.
          332  +*/
          333  +static int sqliteBdb1Fetch(DbbeCursor *pCursr, int nKey, char *pKey){
          334  +  DBT key;
          335  +  key.size = nKey;
          336  +  key.data = pKey;
          337  +  datumClear(&pCursr->key);
          338  +  datumClear(&pCursr->data);
          339  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          340  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
          341  +  }
          342  +  return pCursr->data.dptr!=0;
          343  +}
          344  +
          345  +/*
          346  +** Return 1 if the given key is already in the table.  Return 0
          347  +** if it is not.
          348  +*/
          349  +static int sqliteBdb1Test(DbbeCursor *pCursr, int nKey, char *pKey){
          350  +  DBT key;
          351  +  int result = 0;
          352  +  key.dsize = nKey;
          353  +  key.dptr = pKey;
          354  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          355  +    result = gdbm_exists(pCursr->pFile->dbf, key);
          356  +  }
          357  +  return result;
          358  +}
          359  +
          360  +/*
          361  +** Copy bytes from the current key or data into a buffer supplied by
          362  +** the calling function.  Return the number of bytes copied.
          363  +*/
          364  +static
          365  +int sqliteBdb1CopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
          366  +  int n;
          367  +  if( offset>=pCursr->key.dsize ) return 0;
          368  +  if( offset+size>pCursr->key.dsize ){
          369  +    n = pCursr->key.dsize - offset;
          370  +  }else{
          371  +    n = size;
          372  +  }
          373  +  memcpy(zBuf, &pCursr->key.dptr[offset], n);
          374  +  return n;
          375  +}
          376  +static
          377  +int sqliteBdb1CopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
          378  +  int n;
          379  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          380  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          381  +    pCursr->readPending = 0;
          382  +  }
          383  +  if( offset>=pCursr->data.dsize ) return 0;
          384  +  if( offset+size>pCursr->data.dsize ){
          385  +    n = pCursr->data.dsize - offset;
          386  +  }else{
          387  +    n = size;
          388  +  }
          389  +  memcpy(zBuf, &pCursr->data.dptr[offset], n);
          390  +  return n;
          391  +}
          392  +
          393  +/*
          394  +** Return a pointer to bytes from the key or data.  The data returned
          395  +** is ephemeral.
          396  +*/
          397  +static char *sqliteBdb1ReadKey(DbbeCursor *pCursr, int offset){
          398  +  if( offset<0 || offset>=pCursr->key.dsize ) return "";
          399  +  return &pCursr->key.dptr[offset];
          400  +}
          401  +static char *sqliteBdb1ReadData(DbbeCursor *pCursr, int offset){
          402  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          403  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          404  +    pCursr->readPending = 0;
          405  +  }
          406  +  if( offset<0 || offset>=pCursr->data.dsize ) return "";
          407  +  return &pCursr->data.dptr[offset];
          408  +}
          409  +
          410  +/*
          411  +** Return the total number of bytes in either data or key.
          412  +*/
          413  +static int sqliteBdb1KeyLength(DbbeCursor *pCursr){
          414  +  return pCursr->key.dsize;
          415  +}
          416  +static int sqliteBdb1DataLength(DbbeCursor *pCursr){
          417  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          418  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          419  +    pCursr->readPending = 0;
          420  +  }
          421  +  return pCursr->data.dsize;
          422  +}
          423  +
          424  +/*
          425  +** Make is so that the next call to sqliteNextKey() finds the first
          426  +** key of the table.
          427  +*/
          428  +static int sqliteBdb1Rewind(DbbeCursor *pCursr){
          429  +  pCursr->needRewind = 1;
          430  +  return SQLITE_OK;
          431  +}
          432  +
          433  +/*
          434  +** Read the next key from the table.  Return 1 on success.  Return
          435  +** 0 if there are no more keys.
          436  +*/
          437  +static int sqliteBdb1NextKey(DbbeCursor *pCursr){
          438  +  DBT nextkey;
          439  +  int rc;
          440  +  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
          441  +    pCursr->readPending = 0;
          442  +    return 0;
          443  +  }
          444  +  if( pCursr->needRewind ){
          445  +    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
          446  +    pCursr->needRewind = 0;
          447  +  }else{
          448  +    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
          449  +  }
          450  +  datumClear(&pCursr->key);
          451  +  datumClear(&pCursr->data);
          452  +  pCursr->key = nextkey;
          453  +  if( pCursr->key.dptr ){
          454  +    pCursr->readPending = 1;
          455  +    rc = 1;
          456  +  }else{
          457  +    pCursr->needRewind = 1;
          458  +    pCursr->readPending = 0;
          459  +    rc = 0;
          460  +  }
          461  +  return rc;
          462  +}
          463  +
          464  +/*
          465  +** Get a new integer key.
          466  +*/
          467  +static int sqliteBdb1New(DbbeCursor *pCursr){
          468  +  int iKey;
          469  +  DBT key;
          470  +  int go = 1;
          471  +
          472  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
          473  +  while( go ){
          474  +    iKey = sqliteRandomInteger();
          475  +    if( iKey==0 ) continue;
          476  +    key.dptr = (char*)&iKey;
          477  +    key.dsize = 4;
          478  +    go = gdbm_exists(pCursr->pFile->dbf, key);
          479  +  }
          480  +  return iKey;
          481  +}   
          482  +
          483  +/*
          484  +** Write an entry into the table.  Overwrite any prior entry with the
          485  +** same key.
          486  +*/
          487  +static int sqliteBdb1Put(
          488  +  DbbeCursor *pCursr,  /* Write to the database associated with this cursor */
          489  +  int nKey,            /* Number of bytes in the key */
          490  +  char *pKey,          /* The data for the key */
          491  +  int nData,           /* Number of bytes of data */
          492  +  char *pData          /* The data */
          493  +){
          494  +  DBT data, key;
          495  +  int rc;
          496  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
          497  +  data.dsize = nData;
          498  +  data.dptr = pData;
          499  +  key.dsize = nKey;
          500  +  key.dptr = pKey;
          501  +  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
          502  +  if( rc ) rc = SQLITE_ERROR;
          503  +  datumClear(&pCursr->key);
          504  +  datumClear(&pCursr->data);
          505  +  return rc;
          506  +}
          507  +
          508  +/*
          509  +** Remove an entry from a table, if the entry exists.
          510  +*/
          511  +static int sqliteBdb1Delete(DbbeCursor *pCursr, int nKey, char *pKey){
          512  +  DBT key;
          513  +  int rc;
          514  +  datumClear(&pCursr->key);
          515  +  datumClear(&pCursr->data);
          516  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
          517  +  key.dsize = nKey;
          518  +  key.dptr = pKey;
          519  +  rc = gdbm_delete(pCursr->pFile->dbf, key);
          520  +  if( rc ) rc = SQLITE_ERROR;
          521  +  return rc;
          522  +}
          523  +
          524  +/*
          525  +** Open a temporary file.  The file is located in the same directory
          526  +** as the rest of the database.
          527  +*/
          528  +static int sqliteBdb1OpenTempFile(Dbbe *pDbbe, FILE **ppFile){
          529  +  Dbbex *pBe = (Dbbex*)pDbbe;
          530  +  return sqliteDbbeOpenTempFile(pBe->zDir, pDbbe, ppFile);
          531  +}
          532  +
          533  +/*
          534  +** This variable contains pointers to all of the access methods
          535  +** used to implement the GDBM backend.
          536  +*/
          537  +static struct DbbeMethods gdbmMethods = {
          538  +  /* n         Close */   sqliteBdb1Close,
          539  +  /*      OpenCursor */   sqliteBdb1OpenCursor,
          540  +  /*       DropTable */   sqliteBdb1DropTable,
          541  +  /* ReorganizeTable */   sqliteBdb1ReorganizeTable,
          542  +  /*     CloseCursor */   sqliteBdb1CloseCursor,
          543  +  /*           Fetch */   sqliteBdb1Fetch,
          544  +  /*            Test */   sqliteBdb1Test,
          545  +  /*         CopyKey */   sqliteBdb1CopyKey,
          546  +  /*        CopyData */   sqliteBdb1CopyData,
          547  +  /*         ReadKey */   sqliteBdb1ReadKey,
          548  +  /*        ReadData */   sqliteBdb1ReadData,
          549  +  /*       KeyLength */   sqliteBdb1KeyLength,
          550  +  /*      DataLength */   sqliteBdb1DataLength,
          551  +  /*         NextKey */   sqliteBdb1NextKey,
          552  +  /*          Rewind */   sqliteBdb1Rewind,
          553  +  /*             New */   sqliteBdb1New,
          554  +  /*             Put */   sqliteBdb1Put,
          555  +  /*          Delete */   sqliteBdb1Delete,
          556  +  /*    OpenTempFile */   sqliteBdb1OpenTempFile,
          557  +  /*   CloseTempFile */   sqliteDbbeCloseTempFile
          558  +};
          559  +
          560  +
          561  +/*
          562  +** This routine opens a new database.  For the GDBM driver
          563  +** implemented here, the database name is the name of the directory
          564  +** containing all the files of the database.
          565  +**
          566  +** If successful, a pointer to the Dbbe structure is returned.
          567  +** If there are errors, an appropriate error message is left
          568  +** in *pzErrMsg and NULL is returned.
          569  +*/
          570  +Dbbe *sqliteBdb1Open(
          571  +  const char *zName,     /* The name of the database */
          572  +  int writeFlag,         /* True if we will be writing to the database */
          573  +  int createFlag,        /* True to create database if it doesn't exist */
          574  +  char **pzErrMsg        /* Write error messages (if any) here */
          575  +){
          576  +  Dbbex *pNew;
          577  +  struct stat statbuf;
          578  +  char *zMaster;
          579  +
          580  +  if( !writeFlag ) createFlag = 0;
          581  +  if( stat(zName, &statbuf)!=0 ){
          582  +    if( createFlag ) mkdir(zName, 0750);
          583  +    if( stat(zName, &statbuf)!=0 ){
          584  +      sqliteSetString(pzErrMsg, createFlag ? 
          585  +         "can't find or create directory \"" : "can't find directory \"",
          586  +         zName, "\"", 0);
          587  +      return 0;
          588  +    }
          589  +  }
          590  +  if( !S_ISDIR(statbuf.st_mode) ){
          591  +    sqliteSetString(pzErrMsg, "not a directory: \"", zName, "\"", 0);
          592  +    return 0;
          593  +  }
          594  +  if( access(zName, writeFlag ? (X_OK|W_OK|R_OK) : (X_OK|R_OK)) ){
          595  +    sqliteSetString(pzErrMsg, "access permission denied", 0);
          596  +    return 0;
          597  +  }
          598  +  zMaster = 0;
          599  +  sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0);
          600  +  if( stat(zMaster, &statbuf)==0
          601  +   && access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
          602  +    sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
          603  +    sqliteFree(zMaster);
          604  +    return 0;
          605  +  }
          606  +  sqliteFree(zMaster);
          607  +  pNew = sqliteMalloc(sizeof(Dbbex) + strlen(zName) + 1);
          608  +  if( pNew==0 ){
          609  +    sqliteSetString(pzErrMsg, "out of memory", 0);
          610  +    return 0;
          611  +  }
          612  +  pNew->dbbe.x = &gdbmMethods;
          613  +  pNew->zDir = (char*)&pNew[1];
          614  +  strcpy(pNew->zDir, zName);
          615  +  pNew->write = writeFlag;
          616  +  pNew->pOpen = 0;
          617  +  return &pNew->dbbe;
          618  +}

Added src/ex/dbbemird.c.

            1  +/*
            2  +** Copyright (c) 2000 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** This file contains code to implement the database backend (DBBE)
           25  +** for sqlite.  The database backend is the interface between
           26  +** sqlite and the code that does the actually reading and writing
           27  +** of information to the disk.
           28  +**
           29  +** This file uses GDBM as the database backend.  It should be
           30  +** relatively simple to convert to a different database such
           31  +** as NDBM, SDBM, or BerkeleyDB.
           32  +**
           33  +** $Id: dbbemird.c,v 1.1 2001/02/11 16:56:24 drh Exp $
           34  +*/
           35  +#include "sqliteInt.h"
           36  +#include <gdbm.h>
           37  +#include <sys/stat.h>
           38  +#include <unistd.h>
           39  +#include <ctype.h>
           40  +#include <time.h>
           41  +
           42  +/*
           43  +** Information about each open disk file is an instance of this 
           44  +** structure.  There will only be one such structure for each
           45  +** disk file.  If the VDBE opens the same file twice (as will happen
           46  +** for a self-join, for example) then two DbbeCursor structures are
           47  +** created but there is only a single BeFile structure with an
           48  +** nRef of 2.
           49  +*/
           50  +typedef struct BeFile BeFile;
           51  +struct BeFile {
           52  +  char *zName;            /* Name of the file */
           53  +  GDBM_FILE dbf;          /* The file itself */
           54  +  int nRef;               /* Number of references */
           55  +  int delOnClose;         /* Delete when closing */
           56  +  int writeable;          /* Opened for writing */
           57  +  BeFile *pNext, *pPrev;  /* Next and previous on list of open files */
           58  +};
           59  +
           60  +/*
           61  +** The following structure holds the current state of the RC4 algorithm.
           62  +** We use RC4 as a random number generator.  Each call to RC4 gives
           63  +** a random 8-bit number.
           64  +**
           65  +** Nothing in this file or anywhere else in SQLite does any kind of
           66  +** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
           67  +** number generator) not as an encryption device.
           68  +*/
           69  +struct rc4 {
           70  +  int i, j;
           71  +  int s[256];
           72  +};
           73  +
           74  +/*
           75  +** The following structure contains all information used by GDBM
           76  +** database driver.  This is a subclass of the Dbbe structure.
           77  +*/
           78  +typedef struct Dbbex Dbbex;
           79  +struct Dbbex {
           80  +  Dbbe dbbe;         /* The base class */
           81  +  char *zDir;        /* The directory containing the database */
           82  +  int write;         /* True for write permission */
           83  +  BeFile *pOpen;     /* List of open files */
           84  +  int nTemp;         /* Number of temporary files created */
           85  +  FILE **apTemp;     /* Space to hold temporary file pointers */
           86  +  char **azTemp;     /* Names of the temporary files */
           87  +  struct rc4 rc4;    /* The random number generator */
           88  +};
           89  +
           90  +/*
           91  +** An cursor into a database file is an instance of the following structure.
           92  +** There can only be a single BeFile structure for each disk file, but
           93  +** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
           94  +** a cursor pointing to a particular part of the open BeFile.  The
           95  +** BeFile.nRef field hold a count of the number of DbbeCursor structures
           96  +** associated with the same disk file.
           97  +*/
           98  +struct DbbeCursor {
           99  +  Dbbex *pBe;        /* The database of which this record is a part */
          100  +  BeFile *pFile;     /* The database file for this table */
          101  +  datum key;         /* Most recently used key */
          102  +  datum data;        /* Most recent data */
          103  +  int needRewind;    /* Next key should be the first */
          104  +  int readPending;   /* The fetch hasn't actually been done yet */
          105  +};
          106  +
          107  +/*
          108  +** Initialize the RC4 PRNG.  "seed" is a pointer to some random
          109  +** data used to initialize the PRNG.  
          110  +*/
          111  +static void rc4init(struct rc4 *p, char *seed, int seedlen){
          112  +  int i;
          113  +  char k[256];
          114  +  p->j = 0;
          115  +  p->i = 0;
          116  +  for(i=0; i<256; i++){
          117  +    p->s[i] = i;
          118  +    k[i] = seed[i%seedlen];
          119  +  }
          120  +  for(i=0; i<256; i++){
          121  +    int t;
          122  +    p->j = (p->j + p->s[i] + k[i]) & 0xff;
          123  +    t = p->s[p->j];
          124  +    p->s[p->j] = p->s[i];
          125  +    p->s[i] = t;
          126  +  }
          127  +}
          128  +
          129  +/*
          130  +** Get a single 8-bit random value from the RC4 PRNG.
          131  +*/
          132  +static int rc4byte(struct rc4 *p){
          133  +  int t;
          134  +  p->i = (p->i + 1) & 0xff;
          135  +  p->j = (p->j + p->s[p->i]) & 0xff;
          136  +  t = p->s[p->i];
          137  +  p->s[p->i] = p->s[p->j];
          138  +  p->s[p->j] = t;
          139  +  t = p->s[p->i] + p->s[p->j];
          140  +  return t & 0xff;
          141  +}
          142  +
          143  +/*
          144  +** The "mkdir()" function only takes one argument under Windows.
          145  +*/
          146  +#if OS_WIN
          147  +# define mkdir(A,B) mkdir(A)
          148  +#endif
          149  +
          150  +/*
          151  +** Forward declaration
          152  +*/
          153  +static void sqliteGdbmCloseCursor(DbbeCursor *pCursr);
          154  +
          155  +/*
          156  +** Completely shutdown the given database.  Close all files.  Free all memory.
          157  +*/
          158  +static void sqliteGdbmClose(Dbbe *pDbbe){
          159  +  Dbbex *pBe = (Dbbex*)pDbbe;
          160  +  BeFile *pFile, *pNext;
          161  +  int i;
          162  +  for(pFile=pBe->pOpen; pFile; pFile=pNext){
          163  +    pNext = pFile->pNext;
          164  +    gdbm_close(pFile->dbf);
          165  +    memset(pFile, 0, sizeof(*pFile));   
          166  +    sqliteFree(pFile);
          167  +  }
          168  +  for(i=0; i<pBe->nTemp; i++){
          169  +    if( pBe->apTemp[i]!=0 ){
          170  +      unlink(pBe->azTemp[i]);
          171  +      fclose(pBe->apTemp[i]);
          172  +      sqliteFree(pBe->azTemp[i]);
          173  +      pBe->apTemp[i] = 0;
          174  +      pBe->azTemp[i] = 0;
          175  +      break;
          176  +    }
          177  +  }
          178  +  sqliteFree(pBe->azTemp);
          179  +  sqliteFree(pBe->apTemp);
          180  +  memset(pBe, 0, sizeof(*pBe));
          181  +  sqliteFree(pBe);
          182  +}
          183  +
          184  +/*
          185  +** Translate the name of an SQL table (or index) into the name 
          186  +** of a file that holds the key/data pairs for that table or
          187  +** index.  Space to hold the filename is obtained from
          188  +** sqliteMalloc() and must be freed by the calling function.
          189  +*/
          190  +static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
          191  +  char *zFile = 0;
          192  +  int i;
          193  +  sqliteSetString(&zFile, pBe->zDir, "/", zTable, ".tbl", 0);
          194  +  if( zFile==0 ) return 0;
          195  +  for(i=strlen(pBe->zDir)+1; zFile[i]; i++){
          196  +    int c = zFile[i];
          197  +    if( isupper(c) ){
          198  +      zFile[i] = tolower(c);
          199  +    }else if( !isalnum(c) && c!='-' && c!='_' && c!='.' ){
          200  +      zFile[i] = '+';
          201  +    }
          202  +  }
          203  +  return zFile;
          204  +}
          205  +
          206  +/*
          207  +** Generate a random filename with the given prefix.  The new filename
          208  +** is written into zBuf[].  The calling function must insure that
          209  +** zBuf[] is big enough to hold the prefix plus 20 or so extra
          210  +** characters.
          211  +**
          212  +** Very random names are chosen so that the chance of a
          213  +** collision with an existing filename is very very small.
          214  +*/
          215  +static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
          216  +  int i, j;
          217  +  static const char zRandomChars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
          218  +  strcpy(zBuf, zPrefix);
          219  +  j = strlen(zBuf);
          220  +  for(i=0; i<15; i++){
          221  +    int c = rc4byte(pRc4) % (sizeof(zRandomChars) - 1);
          222  +    zBuf[j++] = zRandomChars[c];
          223  +  }
          224  +  zBuf[j] = 0;
          225  +}
          226  +
          227  +/*
          228  +** Open a new table cursor.  Write a pointer to the corresponding
          229  +** DbbeCursor structure into *ppCursr.  Return an integer success
          230  +** code:
          231  +**
          232  +**    SQLITE_OK          It worked!
          233  +**
          234  +**    SQLITE_NOMEM       sqliteMalloc() failed
          235  +**
          236  +**    SQLITE_PERM        Attempt to access a file for which file
          237  +**                       access permission is denied
          238  +**
          239  +**    SQLITE_BUSY        Another thread or process is already using
          240  +**                       the corresponding file and has that file locked.
          241  +**
          242  +**    SQLITE_READONLY    The current thread already has this file open
          243  +**                       readonly but you are trying to open for writing.
          244  +**                       (This can happen if a SELECT callback tries to
          245  +**                       do an UPDATE or DELETE.)
          246  +**
          247  +** If zTable is 0 or "", then a temporary database file is created and
          248  +** a cursor to that temporary file is opened.  The temporary file
          249  +** will be deleted from the disk when it is closed.
          250  +*/
          251  +static int sqliteGdbmOpenCursor(
          252  +  Dbbe *pDbbe,            /* The database the table belongs to */
          253  +  const char *zTable,     /* The SQL name of the file to be opened */
          254  +  int writeable,          /* True to open for writing */
          255  +  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
          256  +){
          257  +  char *zFile;            /* Name of the table file */
          258  +  DbbeCursor *pCursr;     /* The new table cursor */
          259  +  BeFile *pFile;          /* The underlying data file for this table */
          260  +  int rc = SQLITE_OK;     /* Return value */
          261  +  int rw_mask;            /* Permissions mask for opening a table */
          262  +  int mode;               /* Mode for opening a table */
          263  +  Dbbex *pBe = (Dbbex*)pDbbe;
          264  +
          265  +  *ppCursr = 0;
          266  +  pCursr = sqliteMalloc( sizeof(*pCursr) );
          267  +  if( pCursr==0 ) return SQLITE_NOMEM;
          268  +  if( zTable ){
          269  +    zFile = sqliteFileOfTable(pBe, zTable);
          270  +    for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
          271  +      if( strcmp(pFile->zName,zFile)==0 ) break;
          272  +    }
          273  +  }else{
          274  +    pFile = 0;
          275  +    zFile = 0;
          276  +  }
          277  +  if( pFile==0 ){
          278  +    if( writeable ){
          279  +      rw_mask = GDBM_WRCREAT | GDBM_FAST;
          280  +      mode = 0640;
          281  +    }else{
          282  +      rw_mask = GDBM_READER;
          283  +      mode = 0640;
          284  +    }
          285  +    pFile = sqliteMalloc( sizeof(*pFile) );
          286  +    if( pFile==0 ){
          287  +      sqliteFree(zFile);
          288  +      return SQLITE_NOMEM;
          289  +    }
          290  +    if( zFile ){
          291  +      if( !writeable || pBe->write ){
          292  +        pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
          293  +      }else{
          294  +        pFile->dbf = 0;
          295  +      }
          296  +    }else{
          297  +      int limit;
          298  +      struct rc4 *pRc4;
          299  +      char zRandom[50];
          300  +      pRc4 = &pBe->rc4;
          301  +      zFile = 0;
          302  +      limit = 5;
          303  +      do {
          304  +        randomName(&pBe->rc4, zRandom, "_temp_table_");
          305  +        sqliteFree(zFile);
          306  +        zFile = sqliteFileOfTable(pBe, zRandom);
          307  +        pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
          308  +      }while( pFile->dbf==0 && limit-- >= 0);
          309  +      pFile->delOnClose = 1;
          310  +    }
          311  +    pFile->writeable = writeable;
          312  +    pFile->zName = zFile;
          313  +    pFile->nRef = 1;
          314  +    pFile->pPrev = 0;
          315  +    if( pBe->pOpen ){
          316  +      pBe->pOpen->pPrev = pFile;
          317  +    }
          318  +    pFile->pNext = pBe->pOpen;
          319  +    pBe->pOpen = pFile;
          320  +    if( pFile->dbf==0 ){
          321  +      if( !writeable && access(zFile,0) ){
          322  +        /* Trying to read a non-existant file.  This is OK.  All the
          323  +        ** reads will return empty, which is what we want. */
          324  +        rc = SQLITE_OK;   
          325  +      }else if( pBe->write==0 ){
          326  +        rc = SQLITE_READONLY;
          327  +      }else if( access(zFile,W_OK|R_OK) ){
          328  +        rc = SQLITE_PERM;
          329  +      }else{
          330  +        rc = SQLITE_BUSY;
          331  +      }
          332  +    }
          333  +  }else{
          334  +    sqliteFree(zFile);
          335  +    pFile->nRef++;
          336  +    if( writeable && !pFile->writeable ){
          337  +      rc = SQLITE_READONLY;
          338  +    }
          339  +  }
          340  +  pCursr->pBe = pBe;
          341  +  pCursr->pFile = pFile;
          342  +  pCursr->readPending = 0;
          343  +  pCursr->needRewind = 1;
          344  +  if( rc!=SQLITE_OK ){
          345  +    sqliteGdbmCloseCursor(pCursr);
          346  +    *ppCursr = 0;
          347  +  }else{
          348  +    *ppCursr = pCursr;
          349  +  }
          350  +  return rc;
          351  +}
          352  +
          353  +/*
          354  +** Drop a table from the database.  The file on the disk that corresponds
          355  +** to this table is deleted.
          356  +*/
          357  +static void sqliteGdbmDropTable(Dbbe *pBe, const char *zTable){
          358  +  char *zFile;            /* Name of the table file */
          359  +
          360  +  zFile = sqliteFileOfTable((Dbbex*)pBe, zTable);
          361  +  unlink(zFile);
          362  +  sqliteFree(zFile);
          363  +}
          364  +
          365  +/*
          366  +** Close a cursor previously opened by sqliteGdbmOpenCursor().
          367  +**
          368  +** There can be multiple cursors pointing to the same open file.
          369  +** The underlying file is not closed until all cursors have been
          370  +** closed.  This routine decrements the BeFile.nref field of the
          371  +** underlying file and closes the file when nref reaches 0.
          372  +*/
          373  +static void sqliteGdbmCloseCursor(DbbeCursor *pCursr){
          374  +  BeFile *pFile;
          375  +  Dbbex *pBe;
          376  +  if( pCursr==0 ) return;
          377  +  pFile = pCursr->pFile;
          378  +  pBe = pCursr->pBe;
          379  +  pFile->nRef--;
          380  +  if( pFile->dbf!=NULL ){
          381  +    gdbm_sync(pFile->dbf);
          382  +  }
          383  +  if( pFile->nRef<=0 ){
          384  +    if( pFile->dbf!=NULL ){
          385  +      gdbm_close(pFile->dbf);
          386  +    }
          387  +    if( pFile->pPrev ){
          388  +      pFile->pPrev->pNext = pFile->pNext;
          389  +    }else{
          390  +      pBe->pOpen = pFile->pNext;
          391  +    }
          392  +    if( pFile->pNext ){
          393  +      pFile->pNext->pPrev = pFile->pPrev;
          394  +    }
          395  +    if( pFile->delOnClose ){
          396  +      unlink(pFile->zName);
          397  +    }
          398  +    sqliteFree(pFile->zName);
          399  +    memset(pFile, 0, sizeof(*pFile));
          400  +    sqliteFree(pFile);
          401  +  }
          402  +  if( pCursr->key.dptr ) free(pCursr->key.dptr);
          403  +  if( pCursr->data.dptr ) free(pCursr->data.dptr);
          404  +  memset(pCursr, 0, sizeof(*pCursr));
          405  +  sqliteFree(pCursr);
          406  +}
          407  +
          408  +/*
          409  +** Reorganize a table to reduce search times and disk usage.
          410  +*/
          411  +static int sqliteGdbmReorganizeTable(Dbbe *pBe, const char *zTable){
          412  +  DbbeCursor *pCrsr;
          413  +  int rc;
          414  +
          415  +  rc = sqliteGdbmOpenCursor(pBe, zTable, 1, &pCrsr);
          416  +  if( rc!=SQLITE_OK ){
          417  +    return rc;
          418  +  }
          419  +  if( pCrsr && pCrsr->pFile && pCrsr->pFile->dbf ){
          420  +    gdbm_reorganize(pCrsr->pFile->dbf);
          421  +  }
          422  +  if( pCrsr ){
          423  +    sqliteGdbmCloseCursor(pCrsr);
          424  +  }
          425  +  return SQLITE_OK;
          426  +}
          427  +
          428  +/*
          429  +** Clear the given datum
          430  +*/
          431  +static void datumClear(datum *p){
          432  +  if( p->dptr ) free(p->dptr);
          433  +  p->dptr = 0;
          434  +  p->dsize = 0;
          435  +}
          436  +
          437  +/*
          438  +** Fetch a single record from an open cursor.  Return 1 on success
          439  +** and 0 on failure.
          440  +*/
          441  +static int sqliteGdbmFetch(DbbeCursor *pCursr, int nKey, char *pKey){
          442  +  datum key;
          443  +  key.dsize = nKey;
          444  +  key.dptr = pKey;
          445  +  datumClear(&pCursr->key);
          446  +  datumClear(&pCursr->data);
          447  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          448  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
          449  +  }
          450  +  return pCursr->data.dptr!=0;
          451  +}
          452  +
          453  +/*
          454  +** Return 1 if the given key is already in the table.  Return 0
          455  +** if it is not.
          456  +*/
          457  +static int sqliteGdbmTest(DbbeCursor *pCursr, int nKey, char *pKey){
          458  +  datum key;
          459  +  int result = 0;
          460  +  key.dsize = nKey;
          461  +  key.dptr = pKey;
          462  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          463  +    result = gdbm_exists(pCursr->pFile->dbf, key);
          464  +  }
          465  +  return result;
          466  +}
          467  +
          468  +/*
          469  +** Copy bytes from the current key or data into a buffer supplied by
          470  +** the calling function.  Return the number of bytes copied.
          471  +*/
          472  +static
          473  +int sqliteGdbmCopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
          474  +  int n;
          475  +  if( offset>=pCursr->key.dsize ) return 0;
          476  +  if( offset+size>pCursr->key.dsize ){
          477  +    n = pCursr->key.dsize - offset;
          478  +  }else{
          479  +    n = size;
          480  +  }
          481  +  memcpy(zBuf, &pCursr->key.dptr[offset], n);
          482  +  return n;
          483  +}
          484  +static
          485  +int sqliteGdbmCopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
          486  +  int n;
          487  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          488  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          489  +    pCursr->readPending = 0;
          490  +  }
          491  +  if( offset>=pCursr->data.dsize ) return 0;
          492  +  if( offset+size>pCursr->data.dsize ){
          493  +    n = pCursr->data.dsize - offset;
          494  +  }else{
          495  +    n = size;
          496  +  }
          497  +  memcpy(zBuf, &pCursr->data.dptr[offset], n);
          498  +  return n;
          499  +}
          500  +
          501  +/*
          502  +** Return a pointer to bytes from the key or data.  The data returned
          503  +** is ephemeral.
          504  +*/
          505  +static char *sqliteGdbmReadKey(DbbeCursor *pCursr, int offset){
          506  +  if( offset<0 || offset>=pCursr->key.dsize ) return "";
          507  +  return &pCursr->key.dptr[offset];
          508  +}
          509  +static char *sqliteGdbmReadData(DbbeCursor *pCursr, int offset){
          510  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          511  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          512  +    pCursr->readPending = 0;
          513  +  }
          514  +  if( offset<0 || offset>=pCursr->data.dsize ) return "";
          515  +  return &pCursr->data.dptr[offset];
          516  +}
          517  +
          518  +/*
          519  +** Return the total number of bytes in either data or key.
          520  +*/
          521  +static int sqliteGdbmKeyLength(DbbeCursor *pCursr){
          522  +  return pCursr->key.dsize;
          523  +}
          524  +static int sqliteGdbmDataLength(DbbeCursor *pCursr){
          525  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          526  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          527  +    pCursr->readPending = 0;
          528  +  }
          529  +  return pCursr->data.dsize;
          530  +}
          531  +
          532  +/*
          533  +** Make is so that the next call to sqliteNextKey() finds the first
          534  +** key of the table.
          535  +*/
          536  +static int sqliteGdbmRewind(DbbeCursor *pCursr){
          537  +  pCursr->needRewind = 1;
          538  +  return SQLITE_OK;
          539  +}
          540  +
          541  +/*
          542  +** Read the next key from the table.  Return 1 on success.  Return
          543  +** 0 if there are no more keys.
          544  +*/
          545  +static int sqliteGdbmNextKey(DbbeCursor *pCursr){
          546  +  datum nextkey;
          547  +  int rc;
          548  +  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
          549  +    pCursr->readPending = 0;
          550  +    return 0;
          551  +  }
          552  +  if( pCursr->needRewind ){
          553  +    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
          554  +    pCursr->needRewind = 0;
          555  +  }else{
          556  +    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
          557  +  }
          558  +  datumClear(&pCursr->key);
          559  +  datumClear(&pCursr->data);
          560  +  pCursr->key = nextkey;
          561  +  if( pCursr->key.dptr ){
          562  +    pCursr->readPending = 1;
          563  +    rc = 1;
          564  +  }else{
          565  +    pCursr->needRewind = 1;
          566  +    pCursr->readPending = 0;
          567  +    rc = 0;
          568  +  }
          569  +  return rc;
          570  +}
          571  +
          572  +/*
          573  +** Get a new integer key.
          574  +*/
          575  +static int sqliteGdbmNew(DbbeCursor *pCursr){
          576  +  int iKey;
          577  +  datum key;
          578  +  int go = 1;
          579  +  int i;
          580  +  struct rc4 *pRc4;
          581  +
          582  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
          583  +  pRc4 = &pCursr->pBe->rc4;
          584  +  while( go ){
          585  +    iKey = 0;
          586  +    for(i=0; i<4; i++){
          587  +      iKey = (iKey<<8) + rc4byte(pRc4);
          588  +    }
          589  +    if( iKey==0 ) continue;
          590  +    key.dptr = (char*)&iKey;
          591  +    key.dsize = 4;
          592  +    go = gdbm_exists(pCursr->pFile->dbf, key);
          593  +  }
          594  +  return iKey;
          595  +}   
          596  +
          597  +/*
          598  +** Write an entry into the table.  Overwrite any prior entry with the
          599  +** same key.
          600  +*/
          601  +static int
          602  +sqliteGdbmPut(DbbeCursor *pCursr, int nKey,char *pKey,int nData,char *pData){
          603  +  datum data, key;
          604  +  int rc;
          605  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
          606  +  data.dsize = nData;
          607  +  data.dptr = pData;
          608  +  key.dsize = nKey;
          609  +  key.dptr = pKey;
          610  +  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
          611  +  if( rc ) rc = SQLITE_ERROR;
          612  +  datumClear(&pCursr->key);
          613  +  datumClear(&pCursr->data);
          614  +  return rc;
          615  +}
          616  +
          617  +/*
          618  +** Remove an entry from a table, if the entry exists.
          619  +*/
          620  +static int sqliteGdbmDelete(DbbeCursor *pCursr, int nKey, char *pKey){
          621  +  datum key;
          622  +  int rc;
          623  +  datumClear(&pCursr->key);
          624  +  datumClear(&pCursr->data);
          625  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
          626  +  key.dsize = nKey;
          627  +  key.dptr = pKey;
          628  +  rc = gdbm_delete(pCursr->pFile->dbf, key);
          629  +  if( rc ) rc = SQLITE_ERROR;
          630  +  return rc;
          631  +}
          632  +
          633  +/*
          634  +** Open a temporary file.  The file should be deleted when closed.
          635  +**
          636  +** Note that we can't use the old Unix trick of opening the file
          637  +** and then immediately unlinking the file.  That works great
          638  +** under Unix, but fails when we try to port to Windows.
          639  +*/
          640  +static int sqliteGdbmOpenTempFile(Dbbe *pDbbe, FILE **ppFile){
          641  +  char *zFile;         /* Full name of the temporary file */
          642  +  char zBuf[50];       /* Base name of the temporary file */
          643  +  int i;               /* Loop counter */
          644  +  int limit;           /* Prevent an infinite loop */
          645  +  int rc = SQLITE_OK;  /* Value returned by this function */
          646  +  Dbbex *pBe = (Dbbex*)pDbbe;
          647  +
          648  +  for(i=0; i<pBe->nTemp; i++){
          649  +    if( pBe->apTemp[i]==0 ) break;
          650  +  }
          651  +  if( i>=pBe->nTemp ){
          652  +    pBe->nTemp++;
          653  +    pBe->apTemp = sqliteRealloc(pBe->apTemp, pBe->nTemp*sizeof(FILE*) );
          654  +    pBe->azTemp = sqliteRealloc(pBe->azTemp, pBe->nTemp*sizeof(char*) );
          655  +  }
          656  +  if( pBe->apTemp==0 ){
          657  +    *ppFile = 0;
          658  +    return SQLITE_NOMEM;
          659  +  }
          660  +  limit = 4;
          661  +  zFile = 0;
          662  +  do{
          663  +    randomName(&pBe->rc4, zBuf, "/_temp_file_");
          664  +    sqliteFree(zFile);
          665  +    zFile = 0;
          666  +    sqliteSetString(&zFile, pBe->zDir, zBuf, 0);
          667  +  }while( access(zFile,0)==0 && limit-- >= 0 );
          668  +  *ppFile = pBe->apTemp[i] = fopen(zFile, "w+");
          669  +  if( pBe->apTemp[i]==0 ){
          670  +    rc = SQLITE_ERROR;
          671  +    sqliteFree(zFile);
          672  +    pBe->azTemp[i] = 0;
          673  +  }else{
          674  +    pBe->azTemp[i] = zFile;
          675  +  }
          676  +  return rc;
          677  +}
          678  +
          679  +/*
          680  +** Close a temporary file opened using sqliteGdbmOpenTempFile()
          681  +*/
          682  +static void sqliteGdbmCloseTempFile(Dbbe *pDbbe, FILE *f){
          683  +  int i;
          684  +  Dbbex *pBe = (Dbbex*)pDbbe;
          685  +  for(i=0; i<pBe->nTemp; i++){
          686  +    if( pBe->apTemp[i]==f ){
          687  +      unlink(pBe->azTemp[i]);
          688  +      sqliteFree(pBe->azTemp[i]);
          689  +      pBe->apTemp[i] = 0;
          690  +      pBe->azTemp[i] = 0;
          691  +      break;
          692  +    }
          693  +  }
          694  +  fclose(f);
          695  +}
          696  +
          697  +
          698  +/*
          699  +** This routine opens a new database.  For the GDBM driver
          700  +** implemented here, the database name is the name of the directory
          701  +** containing all the files of the database.
          702  +**
          703  +** If successful, a pointer to the Dbbe structure is returned.
          704  +** If there are errors, an appropriate error message is left
          705  +** in *pzErrMsg and NULL is returned.
          706  +*/
          707  +Dbbe *sqliteGdbmOpen(
          708  +  const char *zName,     /* The name of the database */
          709  +  int writeFlag,         /* True if we will be writing to the database */
          710  +  int createFlag,        /* True to create database if it doesn't exist */
          711  +  char **pzErrMsg        /* Write error messages (if any) here */
          712  +){
          713  +  Dbbex *pNew;
          714  +  struct stat statbuf;
          715  +  char *zMaster;
          716  +
          717  +  if( !writeFlag ) createFlag = 0;
          718  +  if( stat(zName, &statbuf)!=0 ){
          719  +    if( createFlag ) mkdir(zName, 0750);
          720  +    if( stat(zName, &statbuf)!=0 ){
          721  +      sqliteSetString(pzErrMsg, createFlag ? 
          722  +         "can't find or create directory \"" : "can't find directory \"",
          723  +         zName, "\"", 0);
          724  +      return 0;
          725  +    }
          726  +  }
          727  +  if( !S_ISDIR(statbuf.st_mode) ){
          728  +    sqliteSetString(pzErrMsg, "not a directory: \"", zName, "\"", 0);
          729  +    return 0;
          730  +  }
          731  +  if( access(zName, writeFlag ? (X_OK|W_OK|R_OK) : (X_OK|R_OK)) ){
          732  +    sqliteSetString(pzErrMsg, "access permission denied", 0);
          733  +    return 0;
          734  +  }
          735  +  zMaster = 0;
          736  +  sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0);
          737  +  if( stat(zMaster, &statbuf)==0
          738  +   && access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
          739  +    sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
          740  +    sqliteFree(zMaster);
          741  +    return 0;
          742  +  }
          743  +  sqliteFree(zMaster);
          744  +  pNew = sqliteMalloc(sizeof(Dbbex) + strlen(zName) + 1);
          745  +  if( pNew==0 ){
          746  +    sqliteSetString(pzErrMsg, "out of memory", 0);
          747  +    return 0;
          748  +  }
          749  +  pNew->dbbe.Close = sqliteGdbmClose;
          750  +  pNew->dbbe.OpenCursor = sqliteGdbmOpenCursor;
          751  +  pNew->dbbe.DropTable = sqliteGdbmDropTable;
          752  +  pNew->dbbe.ReorganizeTable = sqliteGdbmReorganizeTable;
          753  +  pNew->dbbe.CloseCursor = sqliteGdbmCloseCursor;
          754  +  pNew->dbbe.Fetch = sqliteGdbmFetch;
          755  +  pNew->dbbe.Test = sqliteGdbmTest;
          756  +  pNew->dbbe.CopyKey = sqliteGdbmCopyKey;
          757  +  pNew->dbbe.CopyData = sqliteGdbmCopyData;
          758  +  pNew->dbbe.ReadKey = sqliteGdbmReadKey;
          759  +  pNew->dbbe.ReadData = sqliteGdbmReadData;
          760  +  pNew->dbbe.KeyLength = sqliteGdbmKeyLength;
          761  +  pNew->dbbe.DataLength = sqliteGdbmDataLength;
          762  +  pNew->dbbe.NextKey = sqliteGdbmNextKey;
          763  +  pNew->dbbe.Rewind = sqliteGdbmRewind;
          764  +  pNew->dbbe.New = sqliteGdbmNew;
          765  +  pNew->dbbe.Put = sqliteGdbmPut;
          766  +  pNew->dbbe.Delete = sqliteGdbmDelete;
          767  +  pNew->dbbe.OpenTempFile = sqliteGdbmOpenTempFile;
          768  +  pNew->dbbe.CloseTempFile = sqliteGdbmCloseTempFile;
          769  +  pNew->zDir = (char*)&pNew[1];
          770  +  strcpy(pNew->zDir, zName);
          771  +  pNew->write = writeFlag;
          772  +  pNew->pOpen = 0;
          773  +  time(&statbuf.st_ctime);
          774  +  rc4init(&pNew->rc4, (char*)&statbuf, sizeof(statbuf));
          775  +  return &pNew->dbbe;
          776  +}

Added src/ex/pg.c.

            1  +/*
            2  +** Copyright (c) 2001 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** $Id: pg.c,v 1.1 2001/02/11 16:56:24 drh Exp $
           25  +*/
           26  +#include <assert.h>
           27  +#include <sys/types.h>
           28  +#include <sys/stat.h>
           29  +#include <fcntl.h>
           30  +#include <unistd.h>
           31  +#include "sqliteInt.h"
           32  +#include "pg.h"
           33  +
           34  +/*
           35  +** Uncomment the following for a debug trace
           36  +*/
           37  +#if 1
           38  +# define TRACE(X)  printf X; fflush(stdout);
           39  +#endif  
           40  +
           41  +/*
           42  +** Hash table sizes
           43  +*/
           44  +#define J_HASH_SIZE  127  /* Size of the journal page hash table */
           45  +#define PG_HASH_SIZE 349  /* Size of the database page hash table */
           46  +
           47  +/*
           48  +** Forward declaration of structure
           49  +*/
           50  +typedef struct Pghdr Pghdr;
           51  +
           52  +/*
           53  +** All information about a single paging file is contained in an
           54  +** instance of the following structure.
           55  +*/
           56  +struct Pgr {
           57  +  int fdMain;                    /* The main database file */
           58  +  char *zMain;                   /* Name of the database file */
           59  +  int fdJournal;                 /* The journal file */
           60  +  char *zJournal;                /* Name of the journal file */
           61  +  int nMemPg;                    /* Number of memory-resident pages */
           62  +  int nJPg;                      /* Number of pages in the journal */
           63  +  int nDbPg;                     /* Number of pages in the database */
           64  +  int nRefPg;                    /* Number of pages currently in use */
           65  +  Pghdr *pLru, *pMru;            /* Least and most recently used mem-page */
           66  +  Pghdr *pJidx;                  /* List of journal index pages */
           67  +  Pghdr *pAll;                   /* All pages, except journal index pages */
           68  +  u32 aJHash[J_HASH_SIZE];       /* Journal page hash table */
           69  +  Pghdr *aPgHash[PG_HASH_SIZE];  /* Mem-page hash table */
           70  +};
           71  +
           72  +/*
           73  +** Each memory-resident page of the paging file has a header which
           74  +** is an instance of the following structure.
           75  +*/
           76  +struct Pghdr {
           77  +  Pgr *p;            /* Pointer back to the Pgr structure */
           78  +  int nRef;          /* Number of references to this page */
           79  +  int isDirty;       /* TRUE if needs to be written to disk */
           80  +  u32 dbpgno;        /* Page number in the database file */
           81  +  u32 jpgno;         /* Page number in the journal file */
           82  +  Pghdr *pNx;        /* Next page on a list of them all */
           83  +  Pghdr *pLru;       /* Less recently used pages */
           84  +  Pghdr *pMru;       /* More recently used pages */
           85  +  Pghdr *pNxHash;    /* Next with same dbpgno hash */
           86  +  Pghdr *pPvHash;    /* Previous with the same dbpgno hash */
           87  +};
           88  +
           89  +/*
           90  +** For a memory-resident page, the page data comes immediately after
           91  +** the page header.  The following macros can be used to change a 
           92  +** pointer to a page header into a pointer to the data, or vice
           93  +** versa.
           94  +*/
           95  +#define PG_TO_DATA(X)  ((void*)&(X)[1])
           96  +#define DATA_TO_PG(X)  (&((Pghdr*)(X))[-1])
           97  +
           98  +/*
           99  +** The number of in-memory pages that we accumulate before trying
          100  +** to reuse older pages when new ones are requested.
          101  +*/
          102  +#define MX_MEM_PAGE  100
          103  +
          104  +/*
          105  +** The number of journal data pages that come between consecutive 
          106  +** journal index pages.
          107  +*/
          108  +#define N_J_DATAPAGE  (SQLITE_PAGE_SIZE/(2*sizeof(u32)))
          109  +
          110  +/*
          111  +** An index page in the journal consists of an array of N_J_DATAPAGE
          112  +** of the following structures.  There is one instance of the following
          113  +** structure for each of the N_J_DATAPAGE data pages that follow the
          114  +** index.
          115  +**
          116  +** Let the journal page number that a JidxEntry describes be J.  Then
          117  +** the JidxEntry.dbpgno field is the page of the database file that
          118  +** corresponds to the J page in the journal.  The JidxEntry.next_jpgno
          119  +** field hold the number of another journal page that contains
          120  +** a database file page with the same hash as JidxEntry.dbpgno.
          121  +**
          122  +** All information is written to the journal index in big-endian
          123  +** notation.
          124  +*/
          125  +typedef struct JidxEntry JidxEntry;
          126  +struct JidxEntry {
          127  +  char dbpgno[sizeof(u32)];        /* Database page number for this entry */
          128  +  char next_jpgno[sizeof(u32)];    /* Next entry with same hash on dbpgno */
          129  +};
          130  +
          131  +/*
          132  +** Read a page from a file into memory.  Return SQLITE_OK if successful.
          133  +** The "pgno" parameter tells where in the file to read the page.
          134  +** The first page is 1.  Files do not contain a page 0 since a page
          135  +** number of 0 is used to indicate "no such page".
          136  +*/
          137  +static int sqlitePgRead(int fd, char *zBuf, u32 pgno){
          138  +  int got = 0;
          139  +  int amt;
          140  +
          141  +  assert( pgno>0 );
          142  +  assert( fd>=0 );
          143  +  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
          144  +  while( got<SQLITE_PAGE_SIZE ){
          145  +    amt = read(fd, &zBuf[got], SQLITE_PAGE_SIZE - got);
          146  +    if( amt<=0 ){
          147  +      memset(&zBuf[got], 0, SQLITE_PAGE_SIZE - got);
          148  +      return amt==0 ? SQLITE_OK : SQLITE_IOERR;
          149  +    }
          150  +    got += amt;
          151  +  }
          152  +  return SQLITE_OK;
          153  +}
          154  +
          155  +/*
          156  +** Read a page from a file into memory.  Return SQLITE_OK if successful.
          157  +** The "pgno" parameter tells where in the file to write the page.
          158  +** The first page is 1.  Files do not contain a page 0 since a page
          159  +** number of 0 is used to indicate "no such page".
          160  +*/
          161  +static int sqlitePgWrite(int fd, char *zBuf, u32 pgno){
          162  +  int done = 0;
          163  +  int amt;
          164  +
          165  +  assert( pgno>0 );
          166  +  assert( fd>=0 );
          167  +  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
          168  +  while( done<SQLITE_PAGE_SIZE ){
          169  +    amt = write(fd, &zBuf[done], SQLITE_PAGE_SIZE - done);
          170  +    if( amt<=0 ) return SQLITE_IOERR;
          171  +    done += amt;
          172  +  }
          173  +  return SQLITE_OK;
          174  +}
          175  +
          176  +/*
          177  +** Turn four bytes into an integer.  The first byte is always the
          178  +** most significant 8 bits.
          179  +*/
          180  +static u32 sqlitePgGetInt(const char *p){
          181  +  return ((p[0]&0xff)<<24) | ((p[1]&0xff)<<16) | ((p[2]&0xff)<<8) | (p[3]&0xff);
          182  +}
          183  +
          184  +/*
          185  +** Turn an integer into 4 bytes.  The first byte is always the
          186  +** most significant 8 bits.
          187  +*/
          188  +static void sqlitePgPutInt(u32 v, char *p){
          189  +  p[3] = v & 0xff;
          190  +  v >>= 8;
          191  +  p[2] = v & 0xff;
          192  +  v >>= 8;
          193  +  p[1] = v & 0xff;
          194  +  v >>= 8;
          195  +  p[0] = v & 0xff;
          196  +}
          197  +
          198  +/*
          199  +** Check the hash table for an in-memory page.  Return a pointer to
          200  +** the page header if found.  Return NULL if the page is not in memory.
          201  +*/
          202  +static Pghdr *sqlitePgFind(Pgr *p, u32 pgno){
          203  +  int h;
          204  +  Pghdr *pPg;
          205  +
          206  +  if( pgno==0 ) return 0;
          207  +  h = pgno % PG_HASH_SIZE;
          208  +  for(pPg = p->aPgHash[h]; pPg; pPg=pPg->pNxHash){
          209  +    if( pPg->dbpgno==pgno ) return pPg;
          210  +  }
          211  +  TRACE(("PG: data page %u is %#x\n", pgno, (u32)pPg));
          212  +  return 0;
          213  +}
          214  +
          215  +/*
          216  +** Locate and return an index page from the journal.
          217  +**
          218  +** The first page of a journal is the primary index.  Additional
          219  +** index pages are called secondary indices.  Index pages appear
          220  +** in the journal as often as needed.  (If SQLITE_PAGE_SIZE==1024,
          221  +** then there are 1024/sizeof(int)*2 = 128 database between each
          222  +** pair of index pages.)  Journal index pages are not hashed and
          223  +** do no appear on the Pgr.pAll list.  Index pages are on the
          224  +** Pgr.pJidx list only.  Index pages have Pghdr.dbpgno==0.
          225  +**
          226  +** If the requested index page is not already in memory, then a
          227  +** new memory page is created to hold the index.
          228  +**
          229  +** This routine will return a NULL pointer if we run out of memory.
          230  +*/
          231  +static Pghdr *sqlitePgFindJidx(Pgr *p, u32 pgno){
          232  +  Pghdr *pPg;
          233  +
          234  +  assert( pgno % (N_J_DATAPAGE+1) == 1 );
          235  +  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
          236  +    if( pPg->jpgno==pgno ){
          237  +      TRACE(("PG: found j-index %u at %#x\n", pgno, (u32)pPg));
          238  +      return pPg;
          239  +    }
          240  +  }
          241  +  pPg = sqliteMalloc( sizeof(Pghdr)+SQLITE_PAGE_SIZE );
          242  +  if( pPg==0 ) return 0;
          243  +  pPg->jpgno = pgno;
          244  +  pPg->pNx = p->pJidx;
          245  +  p->pJidx = pPg;
          246  +  sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pgno);
          247  +  TRACE(("PG: create j-index %u at %#x\n", pgno, (u32)pPg));
          248  +  return pPg;
          249  +}
          250  +
          251  +/*
          252  +** Look in the journal to see if the given database page is stored
          253  +** in the journal.  If it is, return its journal page number.  If
          254  +** not, return 0.
          255  +*/
          256  +static u32 sqlitePgJournalPageNumber(Pgr *p, u32 dbpgno){
          257  +  u32 jpgno;
          258  +  
          259  +  if( dbpgno==0 ) return 0;
          260  +  jpgno = p->aJHash[dbpgno % J_HASH_SIZE];
          261  +  while( jpgno!=0 ){
          262  +    int idx_num;     /* Which journal index describes page jpgno */
          263  +    int ipgno;       /* Page number for the journal index */
          264  +    int idx_slot;    /* Which entry in index idx_num describes jpgno */
          265  +    Pghdr *pIdxPg;   /* The index page for jpgno */
          266  +    JidxEntry *aIdx; /* The data for the index page */
          267  +
          268  +    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
          269  +    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
          270  +    ipgno = idx_num * (N_J_DATAPAGE + 1) + 1;
          271  +    if( ipgno>p->nJPg ){
          272  +      jpgno = 0;
          273  +      break;
          274  +    }
          275  +    pIdxPg = sqlitePgFindJidx(p, ipgno);
          276  +    assert( pIdxPg!=0 );
          277  +    aIdx = PG_TO_DATA(pIdxPg);
          278  +    if( dbpgno==sqlitePgGetInt(aIdx[idx_slot].dbpgno) ){
          279  +      break;
          280  +    }
          281  +    jpgno = sqlitePgGetInt(aIdx[idx_slot].next_jpgno);
          282  +  }
          283  +  return jpgno;
          284  +}
          285  +
          286  +/*
          287  +** Make a page not dirty by writing it to the journal.
          288  +*/
          289  +static int sqlitePgMakeClean(Pghdr *pPg){
          290  +  Pgr *p = pPg->p;
          291  +  int rc;
          292  +
          293  +  assert( pPg->isDirty );
          294  +  assert( p->fdJournal>=0 );
          295  +  if( pPg->jpgno==0 ){
          296  +    int jpgno;       /* A newly allocate page in the journal */
          297  +    int idx_num;     /* Which journal index describes page jpgno */
          298  +    int idx_slot;    /* Which entry in index idx_num describes jpgno */
          299  +    Pghdr *pIdxPg;   /* The index page for jpgno */
          300  +    JidxEntry *aIdx; /* The data for the index page */
          301  +    int h;           /* The hash value for pPg->dbpgno */
          302  +
          303  +    jpgno = p->nJPg + 1;
          304  +    if( jpgno % (N_J_DATAPAGE + 1) == 1 ){
          305  +      jpgno++;
          306  +    }
          307  +    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
          308  +    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
          309  +    pIdxPg = sqlitePgFindJidx(p, idx_num * (N_J_DATAPAGE + 1) + 1);
          310  +    assert( pIdxPg!=0 );
          311  +    aIdx = PG_TO_DATA(pIdxPg);
          312  +    sqlitePgPutInt(pPg->dbpgno, aIdx[idx_slot].dbpgno);
          313  +    h = pPg->dbpgno % J_HASH_SIZE;
          314  +    sqlitePgPutInt(p->aJHash[h], aIdx[idx_slot].next_jpgno);
          315  +    p->aJHash[h] = jpgno;
          316  +    p->nJPg = jpgno;
          317  +    pPg->jpgno = jpgno;
          318  +    TRACE(("PG: assign d-page %u to j-page %u\n", jpgno, pPg->dbpgno));
          319  +  }
          320  +  rc = sqlitePgWrite(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
          321  +  if( rc==SQLITE_OK ){
          322  +    pPg->isDirty = 0;
          323  +  }
          324  +  return rc;
          325  +}
          326  +
          327  +/*
          328  +** Find the number of pages in the given file by measuring the size
          329  +** of the file.  Return 0 if there is any problem.
          330  +*/
          331  +static int sqlitePgPageCount(int fd){
          332  +  struct stat statbuf;
          333  +  if( fstat(fd, &statbuf)!=0 ) return 0;
          334  +  return statbuf.st_size/SQLITE_PAGE_SIZE;
          335  +}
          336  +
          337  +/*
          338  +** This routine reads the journal and transfers pages from the
          339  +** journal to the database.
          340  +*/
          341  +static int sqlitePgJournalPlayback(Pgr *p){
          342  +  Pghdr *pPg;
          343  +  JidxEntry *aIdx;
          344  +  int nJpg;
          345  +  int jpgno = 1;
          346  +  int i;
          347  +  int dbpgno;
          348  +  int rc;
          349  +  char idx[SQLITE_PAGE_SIZE];
          350  +  char pgbuf[SQLITE_PAGE_SIZE];
          351  +  
          352  +  assert( p->fdJournal>=0 );
          353  +  nJpg = sqlitePgPageCount(p->fdJournal);
          354  +  while( jpgno<=nJpg ){
          355  +    if( !sqlitePgRead(p->fdJournal, idx, jpgno++) ) break;
          356  +    aIdx = (JidxEntry*)idx;
          357  +    for(i=0; i<N_J_DATAPAGE; i++){
          358  +      dbpgno = sqlitePgGetInt(&idx[i]);
          359  +      if( dbpgno==0 ){
          360  +        jpgno = nJpg+1;
          361  +        break;
          362  +      }
          363  +      pPg = sqlitePgFind(p, dbpgno);
          364  +      if( pPg ){
          365  +        rc = sqlitePgWrite(p->fdMain, PG_TO_DATA(pPg), dbpgno);
          366  +        TRACE(("PG: commit j-page %u to d-page %u from memory\n",jpgno,dbpgno));
          367  +      }else{
          368  +        rc = sqlitePgRead(p->fdJournal, pgbuf, jpgno);
          369  +        if( rc!=SQLITE_OK ){
          370  +          return rc;
          371  +        }
          372  +        rc = sqlitePgWrite(p->fdMain, pgbuf, dbpgno);
          373  +        TRACE(("PG: commit j-page %u to d-page %u from disk\n",jpgno,dbpgno));
          374  +      }
          375  +      jpgno++;
          376  +      if( rc!=SQLITE_OK ){
          377  +        return rc;
          378  +      }
          379  +    }
          380  +  }
          381  +  TRACE(("PG: commit complete. deleting the journal.\n"));
          382  +  fsync(p->fdMain);
          383  +  close(p->fdJournal);
          384  +  p->fdJournal = -1;
          385  +  unlink(p->zJournal);
          386  +  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
          387  +    pPg->isDirty = 0;
          388  +    pPg->jpgno = 0;
          389  +  }
          390  +  while( (pPg = p->pJidx)!=0 ){
          391  +    p->pAll = pPg->pNx;
          392  +    sqliteFree(pPg);
          393  +  }
          394  +  return SQLITE_OK;
          395  +}
          396  +
          397  +/*
          398  +** Remove the given page from the LRU list.
          399  +*/
          400  +static void sqlitePgUnlinkLru(Pghdr *pPg){
          401  +  Pgr *p = pPg->p;
          402  +  if( pPg->pLru ){
          403  +    pPg->pLru->pMru = pPg->pLru;
          404  +  }
          405  +  if( pPg->pMru ){
          406  +    pPg->pMru->pLru = pPg->pMru;
          407  +  }
          408  +  if( p->pLru==pPg ){
          409  +    p->pLru = pPg->pLru;
          410  +  }
          411  +  if( p->pMru==pPg ){
          412  +    p->pMru = pPg->pMru;
          413  +  }
          414  +  pPg->pLru = pPg->pMru = 0;
          415  +}
          416  +
          417  +/*
          418  +** Open the database file and make *ppPgr pointer to a structure describing it.
          419  +** Return SQLITE_OK on success or an error code if there is a failure.
          420  +**
          421  +** If there was an unfinished commit, complete it before returnning.
          422  +*/
          423  +int sqlitePgOpen(const char *zFilename, Pgr **ppPgr){
          424  +  Pgr *p;
          425  +  int n;
          426  +
          427  +  n = strlen(zFilename);
          428  +  p = sqliteMalloc( sizeof(*p) + n*2 + 4 );
          429  +  if( p==0 ){
          430  +    *ppPgr = 0;
          431  +    return SQLITE_NOMEM;
          432  +  }
          433  +  p->zMain = (char*)&p[1];
          434  +  strcpy(p->zMain, zFilename);
          435  +  p->zJournal = &p->zMain[n+1];
          436  +  strcpy(p->zJournal, p->zMain);
          437  +  p->zJournal[n] = '~';
          438  +  p->zJournal[n+1] = 0;
          439  +  p->fdJournal = -1;
          440  +  p->fdMain = open(p->zMain, O_CREAT|O_RDWR, 0600);
          441  +  if( p->fdMain<0 ){
          442  +    *ppPgr = 0;
          443  +    sqliteFree(p);
          444  +    return SQLITE_PERM;
          445  +  }
          446  +  p->nDbPg = sqlitePgPageCount(p->fdMain);
          447  +  if( access(p->zJournal, R_OK)==0 ){
          448  +    sqlitePgJournalPlayback(p);
          449  +  }
          450  +  *ppPgr = p;
          451  +  return SQLITE_OK;
          452  +}
          453  +
          454  +/*
          455  +** Close the database file.  Any outstanding transactions are abandoned.
          456  +*/
          457  +int sqlitePgClose(Pgr *p){
          458  +  Pghdr *pPg;
          459  +
          460  +  if( p->fdMain ) close(p->fdMain);
          461  +  if( p->fdJournal ) close(p->fdJournal);
          462  +  unlink(p->zJournal);
          463  +  while( (pPg = p->pAll)!=0 ){
          464  +    p->pAll = pPg->pNx;
          465  +    sqliteFree(pPg);
          466  +  }
          467  +  while( (pPg = p->pJidx)!=0 ){
          468  +    p->pAll = pPg->pNx;
          469  +    sqliteFree(pPg);
          470  +  }
          471  +  sqliteFree(p);
          472  +  return SQLITE_OK;
          473  +}
          474  +
          475  +/*
          476  +** Begin a new transaction.  Return SQLITE_OK on success or an error
          477  +** code if something goes wrong.
          478  +*/
          479  +int sqlitePgBeginTransaction(Pgr *p){
          480  +  assert( p->fdJournal<0 );
          481  +  if( p->nRefPg>0 ){
          482  +     /* release the read lock */
          483  +  }
          484  +  /* write lock the database */
          485  +  p->fdJournal = open(p->zJournal, O_CREAT|O_EXCL|O_RDWR, 0600);
          486  +  if( p->fdJournal<0 ){
          487  +    return SQLITE_PERM;
          488  +  }
          489  +  p->nJPg = 0;
          490  +  TRACE(("PG: begin transaction\n"));
          491  +  return SQLITE_OK;
          492  +}
          493  +
          494  +/*
          495  +** Commit the current transaction.  Return SQLITE_OK or an error code.
          496  +*/
          497  +int sqlitePgCommit(Pgr *p){
          498  +  Pghdr *pPrimaryIdx = 0;
          499  +  Pghdr *pPg;
          500  +  int rc;
          501  +
          502  +  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
          503  +    if( pPg->isDirty ){
          504  +      rc = sqlitePgMakeClean(pPg);
          505  +      if( rc!=SQLITE_OK ){
          506  +        return rc;
          507  +      }
          508  +    }
          509  +  }
          510  +  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
          511  +    if( pPg->jpgno==1 ){
          512  +      pPrimaryIdx = pPg;
          513  +    }else{
          514  +      TRACE(("PG: writing j-index %u\n", pPg->jpgno));
          515  +      rc = sqlitePgMakeClean(pPg);
          516  +      if( rc!=SQLITE_OK ){
          517  +        return rc;
          518  +      }
          519  +    }
          520  +  }
          521  +  assert( pPrimaryIdx!=0 );
          522  +  fsync(p->fdJournal);
          523  +  TRACE(("PG: writing j-index %u\n", pPrimaryIdx->jpgno));
          524  +  rc = sqlitePgMakeClean(pPrimaryIdx);
          525  +  if( rc!=SQLITE_OK ){
          526  +    return rc;
          527  +  }
          528  +  fsync(p->fdJournal);
          529  +  rc = sqlitePgJournalPlayback(p);
          530  +  if( rc!=SQLITE_OK ){
          531  +    return rc;
          532  +  }
          533  +  /* remove write lock from database */
          534  +  if( p->nRefPg>0 ){
          535  +    /* acquire read lock on database */
          536  +  }
          537  +  return SQLITE_OK;
          538  +}
          539  +
          540  +/*
          541  +** Abandon the current transaction.
          542  +*/
          543  +int sqlitePgRollback(Pgr *p){
          544  +  Pghdr *pPg;
          545  +
          546  +  TRACE(("PG: begin rollback\n"));
          547  +  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
          548  +    if( pPg->isDirty || pPg->jpgno!=0 ){
          549  +      pPg->isDirty = 0;
          550  +      pPg->jpgno = 0;
          551  +      if( pPg->nRef>0 ){
          552  +        TRACE(("PG: reloading d-page %u\n", pPg->dbpgno));
          553  +        sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
          554  +      }else{
          555  +        sqlitePgUnlinkLru(pPg);
          556  +      }
          557  +    }
          558  +  }
          559  +  close(p->fdJournal);
          560  +  p->fdJournal = -1;
          561  +  unlink(p->zJournal);
          562  +  while( (pPg = p->pJidx)!=0 ){
          563  +    p->pAll = pPg->pNx;
          564  +    sqliteFree(pPg);
          565  +  }
          566  +  p->nDbPg = sqlitePgPageCount(p->fdMain);
          567  +  /* remove write lock from database */
          568  +  if( p->nRefPg>0 ){
          569  +    /* acquire read lock on database */
          570  +  }
          571  +  return SQLITE_OK;
          572  +}
          573  +
          574  +/*
          575  +** Get a page from the database.  Return a pointer to the data for that
          576  +** page.
          577  +**
          578  +** A NULL pointer will be returned if we run out of memory.
          579  +*/
          580  +int sqlitePgGet(Pgr *p, u32 pgno, void **ppData){
          581  +  Pghdr *pPg;
          582  +  int h;
          583  +
          584  +  pPg = sqlitePgFind(p, pgno);
          585  +  if( pPg ){
          586  +    pPg->nRef++;
          587  +    if( pPg->nRef==1 ){
          588  +      sqlitePgUnlinkLru(pPg);
          589  +      TRACE(("PG: d-page %u pulled from cache\n", pgno));
          590  +    }
          591  +    p->nRefPg++;
          592  +    if( p->nRefPg==1 ){
          593  +      /* Acquire a read lock */
          594  +    }
          595  +    *ppData = PG_TO_DATA(pPg);
          596  +    return SQLITE_OK;
          597  +  }
          598  +  if( p->nMemPg<MX_MEM_PAGE || p->pLru==0 ){
          599  +    pPg = sqliteMalloc( sizeof(Pghdr) + SQLITE_PAGE_SIZE );
          600  +    if( pPg==0 ) return SQLITE_NOMEM;
          601  +    p->nMemPg++;
          602  +    pPg->pNx = p->pAll;
          603  +    p->pAll = pPg;
          604  +    pPg->p = p;
          605  +    TRACE(("PG: new page %d created.\n", p->nMemPg));
          606  +  }else{
          607  +    int rc;
          608  +    pPg = p->pLru;
          609  +    if( pPg->isDirty ){
          610  +      rc = sqlitePgMakeClean(pPg);
          611  +      if( rc!=SQLITE_OK ) return rc;
          612  +    }
          613  +    sqlitePgUnlinkLru(pPg);
          614  +    h = pPg->dbpgno % PG_HASH_SIZE;
          615  +    if( pPg->pPvHash ){
          616  +      pPg->pPvHash->pNxHash = pPg->pNxHash;
          617  +    }else{
          618  +      assert( p->aPgHash[h]==pPg );
          619  +      p->aPgHash[h] = pPg->pNxHash;
          620  +    }
          621  +    if( pPg->pNxHash ){
          622  +      pPg->pNxHash->pPvHash = pPg->pPvHash;
          623  +    }
          624  +    TRACE(("PG: recycling d-page %u to d-page %u\n", pPg->dbpgno, pgno));
          625  +  }
          626  +  pPg->dbpgno = pgno;
          627  +  if( pgno>p->nDbPg ){
          628  +    p->nDbPg = pgno;
          629  +  }
          630  +  h = pgno % PG_HASH_SIZE;
          631  +  pPg->pPvHash = 0;
          632  +  pPg->pNxHash = p->aPgHash[h];
          633  +  if( pPg->pNxHash ){
          634  +    pPg->pNxHash->pPvHash = pPg;
          635  +  }
          636  +  p->aPgHash[h] = pPg;
          637  +  pPg->jpgno = sqlitePgJournalPageNumber(p, pgno);
          638  +  if( pPg->jpgno!=0 ){
          639  +    TRACE(("PG: reading d-page %u content from j-page %u\n", pgno, pPg->jpgno));
          640  +    sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
          641  +  }else if( pPg->dbpgno!=0 ){
          642  +    TRACE(("PG: reading d-page %u from database\n", pgno));
          643  +    sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
          644  +  }else{
          645  +    TRACE(("PG: reading zero page\n");
          646  +    memset(PG_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
          647  +  }
          648  +  pPg->isDirty = 0;
          649  +  pPg->nRef = 1;
          650  +  p->nRefPg++;
          651  +  if( p->nRefPg==1 ){
          652  +    /* Acquire a read lock */
          653  +  }
          654  +  *ppData = PG_TO_DATA(pPg);
          655  +  return SQLITE_OK;
          656  +}
          657  +
          658  +/*
          659  +** Release a reference to a database data page.
          660  +*/
          661  +int sqlitePgUnref(void *pData){
          662  +  Pghdr *pPg = DATA_TO_PG(pData);
          663  +  pPg->nRef--;
          664  +  assert( pPg->nRef>=0 );
          665  +  if( pPg->nRef==0 ){
          666  +    Pgr *p = pPg->p;
          667  +    pPg->pMru = 0;
          668  +    pPg->pLru = p->pLru;
          669  +    p->pLru = pPg;
          670  +    TRACE(("PG: d-page %u is unused\n", pPg->dbpgno));
          671  +    p->nRefPg--;
          672  +    if( p->nRefPg==0 ){
          673  +      /* Release the read lock */
          674  +    }
          675  +  }
          676  +  return SQLITE_OK;
          677  +}
          678  +
          679  +/*
          680  +** The database page in the argument has been modified.  Write it back
          681  +** to the database file on the next commit.
          682  +*/
          683  +int sqlitePgTouch(void *pD){
          684  +  Pghdr *pPg = DATA_TO_PG(pD);
          685  +  assert( pPg->p->fdJournal>=0 );
          686  +  if( pPg->isDirty==0 ){
          687  +    pPg->isDirty = 1;
          688  +    TRACE(("PG: d-page %u is dirty\n", pPg->dbpgno));
          689  +  }
          690  +  return SQLITE_OK;
          691  +}
          692  +
          693  +/*
          694  +** Return the number of the first unused page at the end of the
          695  +** database file.
          696  +*/
          697  +int sqlitePgCount(Pgr *p, u32 *pPgno){
          698  +  *pPgno = p->nDbPg;
          699  +  return SQLITE_OK;
          700  +}
          701  +
          702  +/*
          703  +** Return the page number associated with the given page.
          704  +*/
          705  +u32 sqlitePgNum(void *pD){
          706  +  Pghdr *pPg = DATA_TO_PG(pD);
          707  +  return pPg->dbpgno;
          708  +}

Added src/ex/pg.h.

            1  +/*
            2  +** Copyright (c) 2001 D. Richard Hipp
            3  +**
            4  +** This program is free software; you can redistribute it and/or
            5  +** modify it under the terms of the GNU General Public
            6  +** License as published by the Free Software Foundation; either
            7  +** version 2 of the License, or (at your option) any later version.
            8  +**
            9  +** This program is distributed in the hope that it will be useful,
           10  +** but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12  +** General Public License for more details.
           13  +** 
           14  +** You should have received a copy of the GNU General Public
           15  +** License along with this library; if not, write to the
           16  +** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           17  +** Boston, MA  02111-1307, USA.
           18  +**
           19  +** Author contact information:
           20  +**   drh@hwaci.com
           21  +**   http://www.hwaci.com/drh/
           22  +**
           23  +*************************************************************************
           24  +** $Id: pg.h,v 1.1 2001/02/11 16:56:24 drh Exp $
           25  +*/
           26  +
           27  +typedef struct Pgr Pgr;
           28  +#define SQLITE_PAGE_SIZE 1024
           29  +
           30  +
           31  +int sqlitePgOpen(const char *filename, Pgr **pp);
           32  +int sqlitePgClose(Pgr*);
           33  +int sqlitePgBeginTransaction(Pgr*);
           34  +int sqlitePgCommit(Pgr*);
           35  +int sqlitePgRollback(Pgr*);
           36  +int sqlitePgGet(Pgr*, u32 pgno, void **);
           37  +int sqlitePgUnref(void*);
           38  +int sqlitePgTouch(void*);
           39  +int sqlitePgCount(Pgr*, u32*);
           40  +u32 sqlitePgNum(void*);

Changes to src/main.c.

    22     22   **
    23     23   *************************************************************************
    24     24   ** Main file for the SQLite library.  The routines in this file
    25     25   ** implement the programmer interface to the library.  Routines in
    26     26   ** other files are for internal use by SQLite and should not be
    27     27   ** accessed by users of the library.
    28     28   **
    29         -** $Id: main.c,v 1.24 2001/01/15 22:51:11 drh Exp $
           29  +** $Id: main.c,v 1.25 2001/02/11 16:56:24 drh Exp $
    30     30   */
    31     31   #include "sqliteInt.h"
    32     32   #include <unistd.h>
    33     33   
    34     34   /*
    35     35   ** This is the callback routine for the code that initializes the
    36     36   ** database.  Each callback contains text of a CREATE TABLE or
................................................................................
   120    120     ** The following program invokes its callback on the SQL for each
   121    121     ** table then goes back and invokes the callback on the
   122    122     ** SQL for each index.  The callback will invoke the
   123    123     ** parser to build the internal representation of the
   124    124     ** database scheme.
   125    125     */
   126    126     static VdbeOp initProg[] = {
   127         -    { OP_OpenTbl,    0, 0,  MASTER_NAME},
          127  +    { OP_OpenTbl,  0, 0,  MASTER_NAME},
   128    128       { OP_Next,     0, 9,  0},           /* 1 */
   129    129       { OP_Field,    0, 0,  0},
   130    130       { OP_String,   0, 0,  "meta"},
   131    131       { OP_Ne,       0, 1,  0},
   132    132       { OP_Field,    0, 0,  0},
   133    133       { OP_Field,    0, 3,  0},
   134    134       { OP_Callback, 2, 0,  0},

Deleted src/pg.c.

     1         -/*
     2         -** Copyright (c) 2001 D. Richard Hipp
     3         -**
     4         -** This program is free software; you can redistribute it and/or
     5         -** modify it under the terms of the GNU General Public
     6         -** License as published by the Free Software Foundation; either
     7         -** version 2 of the License, or (at your option) any later version.
     8         -**
     9         -** This program is distributed in the hope that it will be useful,
    10         -** but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    12         -** General Public License for more details.
    13         -** 
    14         -** You should have received a copy of the GNU General Public
    15         -** License along with this library; if not, write to the
    16         -** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    17         -** Boston, MA  02111-1307, USA.
    18         -**
    19         -** Author contact information:
    20         -**   drh@hwaci.com
    21         -**   http://www.hwaci.com/drh/
    22         -**
    23         -*************************************************************************
    24         -** $Id: pg.c,v 1.4 2001/01/25 01:45:41 drh Exp $
    25         -*/
    26         -#include <assert.h>
    27         -#include <sys/types.h>
    28         -#include <sys/stat.h>
    29         -#include <fcntl.h>
    30         -#include <unistd.h>
    31         -#include "sqliteInt.h"
    32         -#include "pg.h"
    33         -
    34         -/*
    35         -** Uncomment the following for a debug trace
    36         -*/
    37         -#if 1
    38         -# define TRACE(X)  printf X; fflush(stdout);
    39         -#endif  
    40         -
    41         -/*
    42         -** Hash table sizes
    43         -*/
    44         -#define J_HASH_SIZE  127  /* Size of the journal page hash table */
    45         -#define PG_HASH_SIZE 349  /* Size of the database page hash table */
    46         -
    47         -/*
    48         -** Forward declaration of structure
    49         -*/
    50         -typedef struct Pghdr Pghdr;
    51         -
    52         -/*
    53         -** All information about a single paging file is contained in an
    54         -** instance of the following structure.
    55         -*/
    56         -struct Pgr {
    57         -  int fdMain;                    /* The main database file */
    58         -  char *zMain;                   /* Name of the database file */
    59         -  int fdJournal;                 /* The journal file */
    60         -  char *zJournal;                /* Name of the journal file */
    61         -  int nMemPg;                    /* Number of memory-resident pages */
    62         -  int nJPg;                      /* Number of pages in the journal */
    63         -  int nDbPg;                     /* Number of pages in the database */
    64         -  int nRefPg;                    /* Number of pages currently in use */
    65         -  Pghdr *pLru, *pMru;            /* Least and most recently used mem-page */
    66         -  Pghdr *pJidx;                  /* List of journal index pages */
    67         -  Pghdr *pAll;                   /* All pages, except journal index pages */
    68         -  u32 aJHash[J_HASH_SIZE];       /* Journal page hash table */
    69         -  Pghdr *aPgHash[PG_HASH_SIZE];  /* Mem-page hash table */
    70         -};
    71         -
    72         -/*
    73         -** Each memory-resident page of the paging file has a header which
    74         -** is an instance of the following structure.
    75         -*/
    76         -struct Pghdr {
    77         -  Pgr *p;            /* Pointer back to the Pgr structure */
    78         -  int nRef;          /* Number of references to this page */
    79         -  int isDirty;       /* TRUE if needs to be written to disk */
    80         -  u32 dbpgno;        /* Page number in the database file */
    81         -  u32 jpgno;         /* Page number in the journal file */
    82         -  Pghdr *pNx;        /* Next page on a list of them all */
    83         -  Pghdr *pLru;       /* Less recently used pages */
    84         -  Pghdr *pMru;       /* More recently used pages */
    85         -  Pghdr *pNxHash;    /* Next with same dbpgno hash */
    86         -  Pghdr *pPvHash;    /* Previous with the same dbpgno hash */
    87         -};
    88         -
    89         -/*
    90         -** For a memory-resident page, the page data comes immediately after
    91         -** the page header.  The following macros can be used to change a 
    92         -** pointer to a page header into a pointer to the data, or vice
    93         -** versa.
    94         -*/
    95         -#define PG_TO_DATA(X)  ((void*)&(X)[1])
    96         -#define DATA_TO_PG(X)  (&((Pghdr*)(X))[-1])
    97         -
    98         -/*
    99         -** The number of in-memory pages that we accumulate before trying
   100         -** to reuse older pages when new ones are requested.
   101         -*/
   102         -#define MX_MEM_PAGE  100
   103         -
   104         -/*
   105         -** The number of journal data pages that come between consecutive 
   106         -** journal index pages.
   107         -*/
   108         -#define N_J_DATAPAGE  (SQLITE_PAGE_SIZE/(2*sizeof(u32)))
   109         -
   110         -/*
   111         -** An index page in the journal consists of an array of N_J_DATAPAGE
   112         -** of the following structures.  There is one instance of the following
   113         -** structure for each of the N_J_DATAPAGE data pages that follow the
   114         -** index.
   115         -**
   116         -** Let the journal page number that a JidxEntry describes be J.  Then
   117         -** the JidxEntry.dbpgno field is the page of the database file that
   118         -** corresponds to the J page in the journal.  The JidxEntry.next_jpgno
   119         -** field hold the number of another journal page that contains
   120         -** a database file page with the same hash as JidxEntry.dbpgno.
   121         -**
   122         -** All information is written to the journal index in big-endian
   123         -** notation.
   124         -*/
   125         -typedef struct JidxEntry JidxEntry;
   126         -struct JidxEntry {
   127         -  char dbpgno[sizeof(u32)];        /* Database page number for this entry */
   128         -  char next_jpgno[sizeof(u32)];    /* Next entry with same hash on dbpgno */
   129         -};
   130         -
   131         -/*
   132         -** Read a page from a file into memory.  Return SQLITE_OK if successful.
   133         -** The "pgno" parameter tells where in the file to read the page.
   134         -** The first page is 1.  Files do not contain a page 0 since a page
   135         -** number of 0 is used to indicate "no such page".
   136         -*/
   137         -static int sqlitePgRead(int fd, char *zBuf, u32 pgno){
   138         -  int got = 0;
   139         -  int amt;
   140         -
   141         -  assert( pgno>0 );
   142         -  assert( fd>=0 );
   143         -  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
   144         -  while( got<SQLITE_PAGE_SIZE ){
   145         -    amt = read(fd, &zBuf[got], SQLITE_PAGE_SIZE - got);
   146         -    if( amt<=0 ){
   147         -      memset(&zBuf[got], 0, SQLITE_PAGE_SIZE - got);
   148         -      return amt==0 ? SQLITE_OK : SQLITE_IOERR;
   149         -    }
   150         -    got += amt;
   151         -  }
   152         -  return SQLITE_OK;
   153         -}
   154         -
   155         -/*
   156         -** Read a page from a file into memory.  Return SQLITE_OK if successful.
   157         -** The "pgno" parameter tells where in the file to write the page.
   158         -** The first page is 1.  Files do not contain a page 0 since a page
   159         -** number of 0 is used to indicate "no such page".
   160         -*/
   161         -static int sqlitePgWrite(int fd, char *zBuf, u32 pgno){
   162         -  int done = 0;
   163         -  int amt;
   164         -
   165         -  assert( pgno>0 );
   166         -  assert( fd>=0 );
   167         -  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
   168         -  while( done<SQLITE_PAGE_SIZE ){
   169         -    amt = write(fd, &zBuf[done], SQLITE_PAGE_SIZE - done);
   170         -    if( amt<=0 ) return SQLITE_IOERR;
   171         -    done += amt;
   172         -  }
   173         -  return SQLITE_OK;
   174         -}
   175         -
   176         -/*
   177         -** Turn four bytes into an integer.  The first byte is always the
   178         -** most significant 8 bits.
   179         -*/
   180         -static u32 sqlitePgGetInt(const char *p){
   181         -  return ((p[0]&0xff)<<24) | ((p[1]&0xff)<<16) | ((p[2]&0xff)<<8) | (p[3]&0xff);
   182         -}
   183         -
   184         -/*
   185         -** Turn an integer into 4 bytes.  The first byte is always the
   186         -** most significant 8 bits.
   187         -*/
   188         -static void sqlitePgPutInt(u32 v, char *p){
   189         -  p[3] = v & 0xff;
   190         -  v >>= 8;
   191         -  p[2] = v & 0xff;
   192         -  v >>= 8;
   193         -  p[1] = v & 0xff;
   194         -  v >>= 8;
   195         -  p[0] = v & 0xff;
   196         -}
   197         -
   198         -/*
   199         -** Check the hash table for an in-memory page.  Return a pointer to
   200         -** the page header if found.  Return NULL if the page is not in memory.
   201         -*/
   202         -static Pghdr *sqlitePgFind(Pgr *p, u32 pgno){
   203         -  int h;
   204         -  Pghdr *pPg;
   205         -
   206         -  if( pgno==0 ) return 0;
   207         -  h = pgno % PG_HASH_SIZE;
   208         -  for(pPg = p->aPgHash[h]; pPg; pPg=pPg->pNxHash){
   209         -    if( pPg->dbpgno==pgno ) return pPg;
   210         -  }
   211         -  TRACE(("PG: data page %u is %#x\n", pgno, (u32)pPg));
   212         -  return 0;
   213         -}
   214         -
   215         -/*
   216         -** Locate and return an index page from the journal.
   217         -**
   218         -** The first page of a journal is the primary index.  Additional
   219         -** index pages are called secondary indices.  Index pages appear
   220         -** in the journal as often as needed.  (If SQLITE_PAGE_SIZE==1024,
   221         -** then there are 1024/sizeof(int)*2 = 128 database between each
   222         -** pair of index pages.)  Journal index pages are not hashed and
   223         -** do no appear on the Pgr.pAll list.  Index pages are on the
   224         -** Pgr.pJidx list only.  Index pages have Pghdr.dbpgno==0.
   225         -**
   226         -** If the requested index page is not already in memory, then a
   227         -** new memory page is created to hold the index.
   228         -**
   229         -** This routine will return a NULL pointer if we run out of memory.
   230         -*/
   231         -static Pghdr *sqlitePgFindJidx(Pgr *p, u32 pgno){
   232         -  Pghdr *pPg;
   233         -
   234         -  assert( pgno % (N_J_DATAPAGE+1) == 1 );
   235         -  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
   236         -    if( pPg->jpgno==pgno ){
   237         -      TRACE(("PG: found j-index %u at %#x\n", pgno, (u32)pPg));
   238         -      return pPg;
   239         -    }
   240         -  }
   241         -  pPg = sqliteMalloc( sizeof(Pghdr)+SQLITE_PAGE_SIZE );
   242         -  if( pPg==0 ) return 0;
   243         -  pPg->jpgno = pgno;
   244         -  pPg->pNx = p->pJidx;
   245         -  p->pJidx = pPg;
   246         -  sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pgno);
   247         -  TRACE(("PG: create j-index %u at %#x\n", pgno, (u32)pPg));
   248         -  return pPg;
   249         -}
   250         -
   251         -/*
   252         -** Look in the journal to see if the given database page is stored
   253         -** in the journal.  If it is, return its journal page number.  If
   254         -** not, return 0.
   255         -*/
   256         -static u32 sqlitePgJournalPageNumber(Pgr *p, u32 dbpgno){
   257         -  u32 jpgno;
   258         -  
   259         -  if( dbpgno==0 ) return 0;
   260         -  jpgno = p->aJHash[dbpgno % J_HASH_SIZE];
   261         -  while( jpgno!=0 ){
   262         -    int idx_num;     /* Which journal index describes page jpgno */
   263         -    int ipgno;       /* Page number for the journal index */
   264         -    int idx_slot;    /* Which entry in index idx_num describes jpgno */
   265         -    Pghdr *pIdxPg;   /* The index page for jpgno */
   266         -    JidxEntry *aIdx; /* The data for the index page */
   267         -
   268         -    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
   269         -    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
   270         -    ipgno = idx_num * (N_J_DATAPAGE + 1) + 1;
   271         -    if( ipgno>p->nJPg ){
   272         -      jpgno = 0;
   273         -      break;
   274         -    }
   275         -    pIdxPg = sqlitePgFindJidx(p, ipgno);
   276         -    assert( pIdxPg!=0 );
   277         -    aIdx = PG_TO_DATA(pIdxPg);
   278         -    if( dbpgno==sqlitePgGetInt(aIdx[idx_slot].dbpgno) ){
   279         -      break;
   280         -    }
   281         -    jpgno = sqlitePgGetInt(aIdx[idx_slot].next_jpgno);
   282         -  }
   283         -  return jpgno;
   284         -}
   285         -
   286         -/*
   287         -** Make a page not dirty by writing it to the journal.
   288         -*/
   289         -static int sqlitePgMakeClean(Pghdr *pPg){
   290         -  Pgr *p = pPg->p;
   291         -  int rc;
   292         -
   293         -  assert( pPg->isDirty );
   294         -  assert( p->fdJournal>=0 );
   295         -  if( pPg->jpgno==0 ){
   296         -    int jpgno;       /* A newly allocate page in the journal */
   297         -    int idx_num;     /* Which journal index describes page jpgno */
   298         -    int idx_slot;    /* Which entry in index idx_num describes jpgno */
   299         -    Pghdr *pIdxPg;   /* The index page for jpgno */
   300         -    JidxEntry *aIdx; /* The data for the index page */
   301         -    int h;           /* The hash value for pPg->dbpgno */
   302         -
   303         -    jpgno = p->nJPg + 1;
   304         -    if( jpgno % (N_J_DATAPAGE + 1) == 1 ){
   305         -      jpgno++;
   306         -    }
   307         -    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
   308         -    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
   309         -    pIdxPg = sqlitePgFindJidx(p, idx_num * (N_J_DATAPAGE + 1) + 1);
   310         -    assert( pIdxPg!=0 );
   311         -    aIdx = PG_TO_DATA(pIdxPg);
   312         -    sqlitePgPutInt(pPg->dbpgno, aIdx[idx_slot].dbpgno);
   313         -    h = pPg->dbpgno % J_HASH_SIZE;
   314         -    sqlitePgPutInt(p->aJHash[h], aIdx[idx_slot].next_jpgno);
   315         -    p->aJHash[h] = jpgno;
   316         -    p->nJPg = jpgno;
   317         -    pPg->jpgno = jpgno;
   318         -    TRACE(("PG: assign d-page %u to j-page %u\n", jpgno, pPg->dbpgno));
   319         -  }
   320         -  rc = sqlitePgWrite(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
   321         -  if( rc==SQLITE_OK ){
   322         -    pPg->isDirty = 0;
   323         -  }
   324         -  return rc;
   325         -}
   326         -
   327         -/*
   328         -** Find the number of pages in the given file by measuring the size
   329         -** of the file.  Return 0 if there is any problem.
   330         -*/
   331         -static int sqlitePgPageCount(int fd){
   332         -  struct stat statbuf;
   333         -  if( fstat(fd, &statbuf)!=0 ) return 0;
   334         -  return statbuf.st_size/SQLITE_PAGE_SIZE;
   335         -}
   336         -
   337         -/*
   338         -** This routine reads the journal and transfers pages from the
   339         -** journal to the database.
   340         -*/
   341         -static int sqlitePgJournalPlayback(Pgr *p){
   342         -  Pghdr *pPg;
   343         -  JidxEntry *aIdx;
   344         -  int nJpg;
   345         -  int jpgno = 1;
   346         -  int i;
   347         -  int dbpgno;
   348         -  int rc;
   349         -  char idx[SQLITE_PAGE_SIZE];
   350         -  char pgbuf[SQLITE_PAGE_SIZE];
   351         -  
   352         -  assert( p->fdJournal>=0 );
   353         -  nJpg = sqlitePgPageCount(p->fdJournal);
   354         -  while( jpgno<=nJpg ){
   355         -    if( !sqlitePgRead(p->fdJournal, idx, jpgno++) ) break;
   356         -    aIdx = (JidxEntry*)idx;
   357         -    for(i=0; i<N_J_DATAPAGE; i++){
   358         -      dbpgno = sqlitePgGetInt(&idx[i]);
   359         -      if( dbpgno==0 ){
   360         -        jpgno = nJpg+1;
   361         -        break;
   362         -      }
   363         -      pPg = sqlitePgFind(p, dbpgno);
   364         -      if( pPg ){
   365         -        rc = sqlitePgWrite(p->fdMain, PG_TO_DATA(pPg), dbpgno);
   366         -        TRACE(("PG: commit j-page %u to d-page %u from memory\n",jpgno,dbpgno));
   367         -      }else{
   368         -        rc = sqlitePgRead(p->fdJournal, pgbuf, jpgno);
   369         -        if( rc!=SQLITE_OK ){
   370         -          return rc;
   371         -        }
   372         -        rc = sqlitePgWrite(p->fdMain, pgbuf, dbpgno);
   373         -        TRACE(("PG: commit j-page %u to d-page %u from disk\n",jpgno,dbpgno));
   374         -      }
   375         -      jpgno++;
   376         -      if( rc!=SQLITE_OK ){
   377         -        return rc;
   378         -      }
   379         -    }
   380         -  }
   381         -  TRACE(("PG: commit complete. deleting the journal.\n"));
   382         -  fsync(p->fdMain);
   383         -  close(p->fdJournal);
   384         -  p->fdJournal = -1;
   385         -  unlink(p->zJournal);
   386         -  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
   387         -    pPg->isDirty = 0;
   388         -    pPg->jpgno = 0;
   389         -  }
   390         -  while( (pPg = p->pJidx)!=0 ){
   391         -    p->pAll = pPg->pNx;
   392         -    sqliteFree(pPg);
   393         -  }
   394         -  return SQLITE_OK;
   395         -}
   396         -
   397         -/*
   398         -** Remove the given page from the LRU list.
   399         -*/
   400         -static void sqlitePgUnlinkLru(Pghdr *pPg){
   401         -  Pgr *p = pPg->p;
   402         -  if( pPg->pLru ){
   403         -    pPg->pLru->pMru = pPg->pLru;
   404         -  }
   405         -  if( pPg->pMru ){
   406         -    pPg->pMru->pLru = pPg->pMru;
   407         -  }
   408         -  if( p->pLru==pPg ){
   409         -    p->pLru = pPg->pLru;
   410         -  }
   411         -  if( p->pMru==pPg ){
   412         -    p->pMru = pPg->pMru;
   413         -  }
   414         -  pPg->pLru = pPg->pMru = 0;
   415         -}
   416         -
   417         -/*
   418         -** Open the database file and make *ppPgr pointer to a structure describing it.
   419         -** Return SQLITE_OK on success or an error code if there is a failure.
   420         -**
   421         -** If there was an unfinished commit, complete it before returnning.
   422         -*/
   423         -int sqlitePgOpen(const char *zFilename, Pgr **ppPgr){
   424         -  Pgr *p;
   425         -  int n;
   426         -
   427         -  n = strlen(zFilename);
   428         -  p = sqliteMalloc( sizeof(*p) + n*2 + 4 );
   429         -  if( p==0 ){
   430         -    *ppPgr = 0;
   431         -    return SQLITE_NOMEM;
   432         -  }
   433         -  p->zMain = (char*)&p[1];
   434         -  strcpy(p->zMain, zFilename);
   435         -  p->zJournal = &p->zMain[n+1];
   436         -  strcpy(p->zJournal, p->zMain);
   437         -  p->zJournal[n] = '~';
   438         -  p->zJournal[n+1] = 0;
   439         -  p->fdJournal = -1;
   440         -  p->fdMain = open(p->zMain, O_CREAT|O_RDWR, 0600);
   441         -  if( p->fdMain<0 ){
   442         -    *ppPgr = 0;
   443         -    sqliteFree(p);
   444         -    return SQLITE_PERM;
   445         -  }
   446         -  p->nDbPg = sqlitePgPageCount(p->fdMain);
   447         -  if( access(p->zJournal, R_OK)==0 ){
   448         -    sqlitePgJournalPlayback(p);
   449         -  }
   450         -  *ppPgr = p;
   451         -  return SQLITE_OK;
   452         -}
   453         -
   454         -/*
   455         -** Close the database file.  Any outstanding transactions are abandoned.
   456         -*/
   457         -int sqlitePgClose(Pgr *p){
   458         -  Pghdr *pPg;
   459         -
   460         -  if( p->fdMain ) close(p->fdMain);
   461         -  if( p->fdJournal ) close(p->fdJournal);
   462         -  unlink(p->zJournal);
   463         -  while( (pPg = p->pAll)!=0 ){
   464         -    p->pAll = pPg->pNx;
   465         -    sqliteFree(pPg);
   466         -  }
   467         -  while( (pPg = p->pJidx)!=0 ){
   468         -    p->pAll = pPg->pNx;
   469         -    sqliteFree(pPg);
   470         -  }
   471         -  sqliteFree(p);
   472         -  return SQLITE_OK;
   473         -}
   474         -
   475         -/*
   476         -** Begin a new transaction.  Return SQLITE_OK on success or an error
   477         -** code if something goes wrong.
   478         -*/
   479         -int sqlitePgBeginTransaction(Pgr *p){
   480         -  assert( p->fdJournal<0 );
   481         -  if( p->nRefPg>0 ){
   482         -     /* release the read lock */
   483         -  }
   484         -  /* write lock the database */
   485         -  p->fdJournal = open(p->zJournal, O_CREAT|O_EXCL|O_RDWR, 0600);
   486         -  if( p->fdJournal<0 ){
   487         -    return SQLITE_PERM;
   488         -  }
   489         -  p->nJPg = 0;
   490         -  TRACE(("PG: begin transaction\n"));
   491         -  return SQLITE_OK;
   492         -}
   493         -
   494         -/*
   495         -** Commit the current transaction.  Return SQLITE_OK or an error code.
   496         -*/
   497         -int sqlitePgCommit(Pgr *p){
   498         -  Pghdr *pPrimaryIdx = 0;
   499         -  Pghdr *pPg;
   500         -  int rc;
   501         -
   502         -  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
   503         -    if( pPg->isDirty ){
   504         -      rc = sqlitePgMakeClean(pPg);
   505         -      if( rc!=SQLITE_OK ){
   506         -        return rc;
   507         -      }
   508         -    }
   509         -  }
   510         -  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
   511         -    if( pPg->jpgno==1 ){
   512         -      pPrimaryIdx = pPg;
   513         -    }else{
   514         -      TRACE(("PG: writing j-index %u\n", pPg->jpgno));
   515         -      rc = sqlitePgMakeClean(pPg);
   516         -      if( rc!=SQLITE_OK ){
   517         -        return rc;
   518         -      }
   519         -    }
   520         -  }
   521         -  assert( pPrimaryIdx!=0 );
   522         -  fsync(p->fdJournal);
   523         -  TRACE(("PG: writing j-index %u\n", pPrimaryIdx->jpgno));
   524         -  rc = sqlitePgMakeClean(pPrimaryIdx);
   525         -  if( rc!=SQLITE_OK ){
   526         -    return rc;
   527         -  }
   528         -  fsync(p->fdJournal);
   529         -  rc = sqlitePgJournalPlayback(p);
   530         -  if( rc!=SQLITE_OK ){
   531         -    return rc;
   532         -  }
   533         -  /* remove write lock from database */
   534         -  if( p->nRefPg>0 ){
   535         -    /* acquire read lock on database */
   536         -  }
   537         -  return SQLITE_OK;
   538         -}
   539         -
   540         -/*
   541         -** Abandon the current transaction.
   542         -*/
   543         -int sqlitePgRollback(Pgr *p){
   544         -  Pghdr *pPg;
   545         -
   546         -  TRACE(("PG: begin rollback\n"));
   547         -  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
   548         -    if( pPg->isDirty || pPg->jpgno!=0 ){
   549         -      pPg->isDirty = 0;
   550         -      pPg->jpgno = 0;
   551         -      if( pPg->nRef>0 ){
   552         -        TRACE(("PG: reloading d-page %u\n", pPg->dbpgno));
   553         -        sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
   554         -      }else{
   555         -        sqlitePgUnlinkLru(pPg);
   556         -      }
   557         -    }
   558         -  }
   559         -  close(p->fdJournal);
   560         -  p->fdJournal = -1;
   561         -  unlink(p->zJournal);
   562         -  while( (pPg = p->pJidx)!=0 ){
   563         -    p->pAll = pPg->pNx;
   564         -    sqliteFree(pPg);
   565         -  }
   566         -  p->nDbPg = sqlitePgPageCount(p->fdMain);
   567         -  /* remove write lock from database */
   568         -  if( p->nRefPg>0 ){
   569         -    /* acquire read lock on database */
   570         -  }
   571         -  return SQLITE_OK;
   572         -}
   573         -
   574         -/*
   575         -** Get a page from the database.  Return a pointer to the data for that
   576         -** page.
   577         -**
   578         -** A NULL pointer will be returned if we run out of memory.
   579         -*/
   580         -int sqlitePgGet(Pgr *p, u32 pgno, void **ppData){
   581         -  Pghdr *pPg;
   582         -  int h;
   583         -
   584         -  pPg = sqlitePgFind(p, pgno);
   585         -  if( pPg ){
   586         -    pPg->nRef++;
   587         -    if( pPg->nRef==1 ){
   588         -      sqlitePgUnlinkLru(pPg);
   589         -      TRACE(("PG: d-page %u pulled from cache\n", pgno));
   590         -    }
   591         -    p->nRefPg++;
   592         -    if( p->nRefPg==1 ){
   593         -      /* Acquire a read lock */
   594         -    }
   595         -    *ppData = PG_TO_DATA(pPg);
   596         -    return SQLITE_OK;
   597         -  }
   598         -  if( p->nMemPg<MX_MEM_PAGE || p->pLru==0 ){
   599         -    pPg = sqliteMalloc( sizeof(Pghdr) + SQLITE_PAGE_SIZE );
   600         -    if( pPg==0 ) return SQLITE_NOMEM;
   601         -    p->nMemPg++;
   602         -    pPg->pNx = p->pAll;
   603         -    p->pAll = pPg;
   604         -    pPg->p = p;
   605         -    TRACE(("PG: new page %d created.\n", p->nMemPg));
   606         -  }else{
   607         -    int rc;
   608         -    pPg = p->pLru;
   609         -    if( pPg->isDirty ){
   610         -      rc = sqlitePgMakeClean(pPg);
   611         -      if( rc!=SQLITE_OK ) return rc;
   612         -    }
   613         -    sqlitePgUnlinkLru(pPg);
   614         -    h = pPg->dbpgno % PG_HASH_SIZE;
   615         -    if( pPg->pPvHash ){
   616         -      pPg->pPvHash->pNxHash = pPg->pNxHash;
   617         -    }else{
   618         -      assert( p->aPgHash[h]==pPg );
   619         -      p->aPgHash[h] = pPg->pNxHash;
   620         -    }
   621         -    if( pPg->pNxHash ){
   622         -      pPg->pNxHash->pPvHash = pPg->pPvHash;
   623         -    }
   624         -    TRACE(("PG: recycling d-page %u to d-page %u\n", pPg->dbpgno, pgno));
   625         -  }
   626         -  pPg->dbpgno = pgno;
   627         -  if( pgno>p->nDbPg ){
   628         -    p->nDbPg = pgno;
   629         -  }
   630         -  h = pgno % PG_HASH_SIZE;
   631         -  pPg->pPvHash = 0;
   632         -  pPg->pNxHash = p->aPgHash[h];
   633         -  if( pPg->pNxHash ){
   634         -    pPg->pNxHash->pPvHash = pPg;
   635         -  }
   636         -  p->aPgHash[h] = pPg;
   637         -  pPg->jpgno = sqlitePgJournalPageNumber(p, pgno);
   638         -  if( pPg->jpgno!=0 ){
   639         -    TRACE(("PG: reading d-page %u content from j-page %u\n", pgno, pPg->jpgno));
   640         -    sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
   641         -  }else if( pPg->dbpgno!=0 ){
   642         -    TRACE(("PG: reading d-page %u from database\n", pgno));
   643         -    sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
   644         -  }else{
   645         -    TRACE(("PG: reading zero page\n");
   646         -    memset(PG_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
   647         -  }
   648         -  pPg->isDirty = 0;
   649         -  pPg->nRef = 1;
   650         -  p->nRefPg++;
   651         -  if( p->nRefPg==1 ){
   652         -    /* Acquire a read lock */
   653         -  }
   654         -  *ppData = PG_TO_DATA(pPg);
   655         -  return SQLITE_OK;
   656         -}
   657         -
   658         -/*
   659         -** Release a reference to a database data page.
   660         -*/
   661         -int sqlitePgUnref(void *pData){
   662         -  Pghdr *pPg = DATA_TO_PG(pData);
   663         -  pPg->nRef--;
   664         -  assert( pPg->nRef>=0 );
   665         -  if( pPg->nRef==0 ){
   666         -    Pgr *p = pPg->p;
   667         -    pPg->pMru = 0;
   668         -    pPg->pLru = p->pLru;
   669         -    p->pLru = pPg;
   670         -    TRACE(("PG: d-page %u is unused\n", pPg->dbpgno));
   671         -    p->nRefPg--;
   672         -    if( p->nRefPg==0 ){
   673         -      /* Release the read lock */
   674         -    }
   675         -  }
   676         -  return SQLITE_OK;
   677         -}
   678         -
   679         -/*
   680         -** The database page in the argument has been modified.  Write it back
   681         -** to the database file on the next commit.
   682         -*/
   683         -int sqlitePgTouch(void *pD){
   684         -  Pghdr *pPg = DATA_TO_PG(pD);
   685         -  assert( pPg->p->fdJournal>=0 );
   686         -  if( pPg->isDirty==0 ){
   687         -    pPg->isDirty = 1;
   688         -    TRACE(("PG: d-page %u is dirty\n", pPg->dbpgno));
   689         -  }
   690         -  return SQLITE_OK;
   691         -}
   692         -
   693         -/*
   694         -** Return the number of the first unused page at the end of the
   695         -** database file.
   696         -*/
   697         -int sqlitePgCount(Pgr *p, u32 *pPgno){
   698         -  *pPgno = p->nDbPg;
   699         -  return SQLITE_OK;
   700         -}
   701         -
   702         -/*
   703         -** Return the page number associated with the given page.
   704         -*/
   705         -u32 sqlitePgNum(void *pD){
   706         -  Pghdr *pPg = DATA_TO_PG(pD);
   707         -  return pPg->dbpgno;
   708         -}

Deleted src/pg.h.

     1         -/*
     2         -** Copyright (c) 2001 D. Richard Hipp
     3         -**
     4         -** This program is free software; you can redistribute it and/or
     5         -** modify it under the terms of the GNU General Public
     6         -** License as published by the Free Software Foundation; either
     7         -** version 2 of the License, or (at your option) any later version.
     8         -**
     9         -** This program is distributed in the hope that it will be useful,
    10         -** but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    12         -** General Public License for more details.
    13         -** 
    14         -** You should have received a copy of the GNU General Public
    15         -** License along with this library; if not, write to the
    16         -** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    17         -** Boston, MA  02111-1307, USA.
    18         -**
    19         -** Author contact information:
    20         -**   drh@hwaci.com
    21         -**   http://www.hwaci.com/drh/
    22         -**
    23         -*************************************************************************
    24         -** $Id: pg.h,v 1.3 2001/01/21 00:58:09 drh Exp $
    25         -*/
    26         -
    27         -typedef struct Pgr Pgr;
    28         -#define SQLITE_PAGE_SIZE 1024
    29         -
    30         -
    31         -int sqlitePgOpen(const char *filename, Pgr **pp);
    32         -int sqlitePgClose(Pgr*);
    33         -int sqlitePgBeginTransaction(Pgr*);
    34         -int sqlitePgCommit(Pgr*);
    35         -int sqlitePgRollback(Pgr*);
    36         -int sqlitePgGet(Pgr*, u32 pgno, void **);
    37         -int sqlitePgUnref(void*);
    38         -int sqlitePgTouch(void*);
    39         -int sqlitePgCount(Pgr*, u32*);
    40         -u32 sqlitePgNum(void*);

Changes to src/tokenize.c.

    23     23   *************************************************************************
    24     24   ** An tokenizer for SQL
    25     25   **
    26     26   ** This file contains C code that splits an SQL input string up into
    27     27   ** individual tokens and sends those tokens one-by-one over to the
    28     28   ** parser for analysis.
    29     29   **
    30         -** $Id: tokenize.c,v 1.16 2000/12/10 18:23:51 drh Exp $
           30  +** $Id: tokenize.c,v 1.17 2001/02/11 16:56:24 drh Exp $
    31     31   */
    32     32   #include "sqliteInt.h"
    33     33   #include <ctype.h>
    34     34   #include <stdlib.h>
    35     35   
    36     36   /*
    37     37   ** All the keywords of the SQL language are stored as in a hash
................................................................................
   304    304     int nErr = 0;
   305    305     int i;
   306    306     void *pEngine;
   307    307     int once = 1;
   308    308     static FILE *trace = 0;
   309    309     extern void *sqliteParserAlloc(void*(*)(int));
   310    310     extern void sqliteParserFree(void*, void(*)(void*));
   311         -  extern int sqliteParser(void*, int, ...);
          311  +  extern int sqliteParser(void*, int, Token, Parse*);
   312    312     extern void sqliteParserTrace(FILE*, char *);
   313    313   
   314    314     pParse->db->flags &= ~SQLITE_Interrupt;
   315    315     pParse->rc = SQLITE_OK;
   316    316     i = 0;
   317    317     sqliteParseInfoReset(pParse);
   318    318     pEngine = sqliteParserAlloc((void*(*)(int))malloc);

Changes to www/changes.tcl.

    12     12   }
    13     13   
    14     14   
    15     15   proc chng {date desc} {
    16     16     puts "<DT><B>$date</B></DT>"
    17     17     puts "<DD><P><UL>$desc</UL></P></DD>"
    18     18   }
           19  +
           20  +chng {2001 Feb 11 (1.0.20)} {
           21  +<li>Merge development changes into the main trunk.  Future work toward
           22  +    using a BTree file structure will use a separate CVS source tree.  This
           23  +    CVS tree will continue to support the GDBM version of SQLite only.</li>
           24  +}
           25  +
           26  +chng {2001 Feb 6 (1.0.19)} {
           27  +<li>Fix a strange (but valid) C declaration that was causing problems
           28  +    for QNX.  No logical changes.</li>
           29  +}
    19     30   
    20     31   chng {2001 Jan 4 (1.0.18)} {
    21     32   <li>Print the offending SQL statement when an error occurs.</li>
    22     33   <li>Do not require commas between constraints in CREATE TABLE statements.</li>
    23     34   <li>Added the "-echo" option to the shell.</li>
    24     35   <li>Changes to comments.</li>
    25     36   }