/ Check-in [8ad996fd]
Login

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

Overview
Comment:Removing some surplus files. (CVS 1723)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8ad996fdac6801768e94ca1710a0a3da03e1e7ea
User & Date: drh 2001-09-15 00:59:33
Context
2001-09-15
13:15
Limit the total data in a single row to 2^16-1 bytes. (CVS 248) check-in: 8fdec4d8 user: drh tags: trunk
00:59
Removing some surplus files. (CVS 1723) check-in: 8ad996fd user: drh tags: trunk
00:58
Release 2.0-alpha-1 (CVS 247) check-in: 264f2331 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Deleted 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.

Deleted 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         -}

Deleted 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);

Deleted 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         -}

Deleted 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         -}

Deleted 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         -}

Deleted 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*);

Deleted src/ex/sizes.tcl.

     1         -
     2         -set sizes {1024 2048 4096 8192 16384 32768}
     3         -set fmt { %-8s}
     4         -
     5         -puts -nonewline "page size: "
     6         -foreach s $sizes {
     7         -  puts -nonewline [format $fmt $s]
     8         -}
     9         -puts ""
    10         -
    11         -puts -nonewline "on leaf:   "
    12         -foreach s $sizes {
    13         -  set x [expr {$s - 18*4}]
    14         -  set p($s) $x
    15         -  puts -nonewline [format $fmt $x]
    16         -}
    17         -puts ""
    18         -
    19         -puts -nonewline "direct:    "
    20         -foreach s $sizes {
    21         -  set x [expr {$p($s) + 10*$s}]
    22         -  set p($s) $x
    23         -  puts -nonewline [format $fmt $x]
    24         -}
    25         -puts ""
    26         -
    27         -puts -nonewline "indirect:  "
    28         -foreach s $sizes {
    29         -  set x [expr {$p($s) + ($s/4.0)*$s}]
    30         -  set p($s) $x
    31         -  puts -nonewline [format $fmt $x]
    32         -}
    33         -puts ""
    34         -
    35         -puts -nonewline "dbl indir: "
    36         -foreach s $sizes {
    37         -  set x [expr {$p($s) + ($s/4.0)*($s/4)*$s}]
    38         -  set p($s) $x
    39         -  puts -nonewline [format $fmt $x]
    40         -}
    41         -puts ""