/ Check-in [df0ff304]
Login

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

Overview
Comment:Working better with Win95. Continued work on the new db.c backend. (CVS 1714)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: df0ff304855bd18c7a3517c500e891b6d006be6a
User & Date: drh 2001-01-31 13:28:08
Context
2001-01-31
13:28
Working better with Win95. Continued work on the new db.c backend. (CVS 181) check-in: f9c55a90 user: drh tags: trunk
13:28
Working better with Win95. Continued work on the new db.c backend. (CVS 1714) check-in: df0ff304 user: drh tags: trunk
2001-01-29
01:27
:-) (CVS 1713) check-in: 3259a531 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/db.c.

    17     17   ** Boston, MA  02111-1307, USA.
    18     18   **
    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24         -** $Id: db.c,v 1.5 2001/01/29 01:27:20 drh Exp $
           24  +** $Id: db.c,v 1.6 2001/01/31 13:28:08 drh Exp $
    25     25   */
    26     26   #include "sqliteInt.h"
    27     27   #include "pg.h"
    28     28   
    29     29   /*
    30     30   ** Everything we need to know about an open database
    31     31   */
    32     32   struct Db {
    33     33     Pgr *pPgr;            /* The pager for the database */
    34     34     DbCursor *pCursor;    /* All open cursors */
    35     35     int inTransaction;    /* True if a transaction is in progress */
    36         -  int nContents;        /* Number of slots in aContents[] */
    37         -  int nAlloc;           /* Space allocated for aContents[] */
    38         -  u32 *aContents;       /* Contents table for the database */
           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     39   };
    40     40   
    41     41   /*
    42     42   ** The maximum depth of a cursor
    43     43   */
    44     44   #define MX_LEVEL 10
    45     45   
................................................................................
    48     48   ** this structure.
    49     49   */
    50     50   typedef struct DbIdxpt DbIdxpt;
    51     51   struct DbIdxpt {
    52     52     int pgno;         /* The page number */
    53     53     u32 *aPage;       /* The page data */
    54     54     int idx;          /* Index into pPage[] */
    55         -  int hashLB;       /* Lower bound on hash at this level */
    56         -  int hashUB;       /* Upper bound on hash at this level */
    57     55   };
    58     56   
    59     57   /*
    60     58   ** Everything we need to know about a cursor
    61     59   */
    62     60   struct DbCursor {
    63     61     Db *pDb;                      /* The whole database */
................................................................................
    65     63     u32 rootPgno;                 /* Root page of table for this cursor */
    66     64     int onEntry;                  /* True if pointing to a table entry */
    67     65     int nLevel;                   /* Number of levels of indexing used */
    68     66     DbIdxpt aLevel[MX_LEVEL];     /* The index levels */
    69     67   };
    70     68   
    71     69   /*
    72         -** Used for rebalancing
    73         -*/
    74         -typedef struct DbEntry DbEntry;
    75         -struct DbEntry {
    76         -  int nByte;      /* Space needed on leaf to record this entry */
    77         -  int pgno;       /* Page on which this entry is currently found */
    78         -  int idx;        /* Index slot in part that points to leaf "pgno" */
    79         -  u32 *aPage;     /* Pointer to the leaf for this entry */
    80         -  u32 *aEntry;    /* Pointer to the actual text of this entry */
    81         -  DbEntry *pNext; /* Next entry in a list of them all */
    82         -};
    83         -typedef struct DbEntrySet DbEntrySet;
    84         -struct DbEntrySet {
    85         -  u32 *pIndex;         /* The index node above the leaf pages being balanced */
    86         -  int nAlloc;          /* Number of slots allocated in aEntry[] */
    87         -  int nEntry;          /* Number of slots in aEntry[] actually used */
    88         -  DbEntry *pFirst;     /* First entry in hash order */
    89         -  DbEntry aEntry[100]; /* Descriptions of actual database entries */
    90         -};
           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
    91    100   
    92    101   /*
    93    102   ** The first word of every page is some combination of these values
    94    103   ** used to indicate its function.
    95    104   */
    96         -#define BLOCK_MAGIC            0x24e47190
    97         -#define BLOCK_INDEX            0x00000001
    98         -#define BLOCK_LEAF             0x00000002
    99         -#define BLOCK_FREE             0x00000003
   100         -#define BLOCK_OVERFLOW         0x00000004
   101         -#define BLOCK_CONTENTS         0x00000005
   102         -#define BLOCK_MAGIC_MASK       0xfffffff8
   103         -#define BLOCK_TYPE_MASK        0x00000007
   104         -
   105         -/*
   106         -** Free blocks:
   107         -**
   108         -**     0.   BLOCK_MAGIC | BLOCK_FREE
   109         -**     1.   address of next block on freelist
   110         -**
   111         -** Leaf blocks:
   112         -**
   113         -**     0.   BLOCK_MAGIC | BLOCK_LEAF 
   114         -**     1.   number of table entries  (only used if a table root block)
   115         -**     entries....
   116         -**         0.  size of this entry (measured in u32's)
   117         -**         1.  hash
   118         -**         2.  keysize  (in bytes)
   119         -**         3.  datasize (in bytes)
   120         -**         4.  payload
   121         -**
   122         -** Payload area:
   123         -**
   124         -**     *   up to LOCAL_PAYLOAD bytes of data
   125         -**     *   10 page number of direct blocks
   126         -**     *   1 indirect block
   127         -**     *   1 double-indirect block
   128         -**
   129         -** Index block:
   130         -**
   131         -**     0.   BLOCK_MAGIC | BLOCK_INDEX
   132         -**     1.   number of table entries  (only used if a table root block)
   133         -**     2.   entries in this index block
   134         -**     entries...
   135         -**         0.  largest hash value for pgno
   136         -**         1.  pgno of subblock
   137         -**
   138         -** Contents block:  (The first page in the file)
   139         -**     0.   BLOCK_MAGIC | BLOCK_CONTENTS
   140         -**     1.   zero
   141         -**     2.   number of bytes of payload
   142         -**     3.   freelist
   143         -**     4... root pages numbers of tables
   144         -*/
          105  +#define BLOCK_PAGE1            0x24e47191
          106  +#define BLOCK_INDEX            0x7ac53b46
          107  +#define BLOCK_LEAF             0x60c45eef
          108  +#define BLOCK_FREE             0x5b2dda47
   145    109   
   146    110   /*
   147    111   ** The number of u32-sized objects that will fit on one page.
   148    112   */
   149    113   #define U32_PER_PAGE  (SQLITE_PAGE_SIZE/sizeof(u32))
   150    114   
   151    115   /*
   152    116   ** Number of direct overflow pages per database entry
   153    117   */
   154    118   #define N_DIRECT  10
   155    119   
   156    120   /*
   157         -** The maximum amount of payload that will fit on on the same
   158         -** page as a leaf, assuming the leaf contains only a single
   159         -** database entry and the entry uses no overflow pages.
          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.
   160    128   */
   161         -#define LOCAL_PAYLOAD  (SQLITE_PAGE_SIZE - (8+N_DIRECT)*sizeof(u32))
          129  +#define LOCAL_PAYLOAD (((U32_PER_PAGE-2)/3 - (6+N_DIRECT))*sizeof(u32))
   162    130   
   163    131   /*
   164    132   ** Allocate a new page.  Return both the page number and a pointer
   165    133   ** to the page data.  The calling function is responsible for unref-ing
   166    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.
   167    139   */
   168    140   int allocPage(Db *pDb, u32 *pPgno, u32 **ppPage){
   169    141     u32 pgno;
   170    142     int rc;
   171    143   
   172         -  if( pDb->aContent==0 ) return SQLITE_NOMEM;
          144  +  if( pDb->aTable==0 ) return SQLITE_NOMEM;
   173    145   
   174    146     /* Try to reuse a page from the freelist
   175    147     */
   176         -  pgno = pDb->aContent[0];
   177         -  if( pgno!=0 ){
   178         -    rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage);
          148  +  if( pDb->freeList==0 ){
          149  +    u32 *pPage;
          150  +    rc = sqlitePgGet(pDb->pPgr, pDb->freeList, &pPage);
   179    151       if( rc==SQLITE_OK ){
   180         -      pDb->aContent[0] = pFree[1];
   181         -      *pPgno = pgno;
   182         -      memset(*ppPage, 0, SQLITE_PAGE_SIZE);
   183         -      return 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);
   184    161       }
   185    162     }
   186    163   
   187    164     /* If the freelist is empty, or we cannot access it,
   188    165     ** then allocate a new page from the end of the file.
   189    166     */
   190    167     if( (rc = sqlitePgCount(pDb->pPgr, &pgno))==SQLITE_OK &&
................................................................................
   196    173     return rc;
   197    174   }
   198    175   
   199    176   /*
   200    177   ** Return a page to the freelist and dereference the page.
   201    178   */
   202    179   static void freePage(DB *pDb, u32 pgno, u32 *aPage){
   203         -  if( pDb->aContent==0 ) return;
   204    180     if( pgno==0 ) return
   205    181     if( aPage==0 ){
   206    182       int rc;
   207    183       rc = sqlitePgGet(pDb->pPgr, pgno, &aPage);
   208    184       if( rc!=SQLITE_OK ) return;
   209    185     }
   210         -  aPage[0] = BLOCK_MAGIC | BLOCK_FREE;
   211         -  aPage[1] = pDb->aContent[0];
          186  +  assert( sqlitePgNum(aPage)==pgno );
          187  +  aPage[0] = BLOCK_FREE;
          188  +  aPage[1] = pDb->freeList;
          189  +  pDb->freeList = pgno;
   212    190     memset(&aPage[2], 0, SQLITE_PAGE_SIZE - 2*sizeof(u32));
   213         -  pDb->aContent[0] = pgno;
   214    191     sqlitePgTouch(aPage);
   215    192     sqlitePgUnref(aPage);
   216    193   }
   217    194   
   218    195   /*
   219    196   ** Return the number of bytes of payload storage required on the leaf
   220    197   ** node to hold the amount of payload specified by the argument.
................................................................................
   531    508       sqlitePgUnref(dblIndirPage);
   532    509     }
   533    510   
   534    511     return SQLITE_OK;
   535    512   }
   536    513   
   537    514   /*
   538         -** Release any and all overflow pages associated with data starting
   539         -** with byte "newSize".  oldSize is the amount of payload before doing
   540         -** the free operation.
          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.
   541    518   */
   542         -static int payloadFree(Db *pDb, u32 *aPage, int newSize, int oldSize){
          519  +static int payloadResize(Db *pDb, u32 *aPage, int oldSize, int newSize){
   543    520     int i, j;          /* Loop counters */
   544    521     int first, last;   /* Indices of first and last pages to be freed */
   545    522     int rc;            /* Return code from sqlitePgGet() */
   546    523   
   547    524     /* Skip over the local data.  We do not need to free it.
   548    525     */
   549    526     if( newSize>=oldSize ) return SQLITE_OK;
................................................................................
   634    611     return SQLITE_OK;    
   635    612   }
   636    613   
   637    614   /*
   638    615   ** Allocate space for the content table in the given Db structure.
   639    616   ** return SQLITE_OK on success and SQLITE_NOMEM if it fails.
   640    617   */
   641         -static int sqliteDbExpandContent(Db *pDb, int newSize){
   642         -  if( pDb->nAlloc>=newSize ) return SQLITE_OK;
   643         -  pDb->nAlloc = newSize;
   644         -  pDb->aContent = sqliteRealloc( pDb->aContent, pDb->nAlloc*sizeof(u32));
   645         -  if( pDb->aContent==0 ){
   646         -    pDb->nContent = 0;
   647         -    pDb->nAlloc = 0;
          618  +static int sqliteDbExpandTableArray(Db *pDb){
          619  +  pDb->aTable = sqliteRealloc( pDb->aTable, pDb->nTable*sizeof(u32));
          620  +  if( pDb->aTable==0 ){
   648    621       pDb->inTranaction = 0;
   649    622       return SQLITE_NOMEM;
   650    623     }
   651    624     return SQLITE_OK;
   652    625   }
   653    626   
   654    627   /*
................................................................................
   672    645     pDb->pCursor = 0;
   673    646     pDb->inTransaction = 0;
   674    647     sqlitePgCount(pDb->pPgr, &nPage);
   675    648     rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   676    649     if( rc!=0 ) goto open_err;
   677    650     if( nPage==0 ){
   678    651       sqlitePgBeginTransaction(pDb->pPgr);
   679         -    aPage1[0] = BLOCK_MAGIC|BLOCK_CONTENT;
   680         -    aPage1[2] = sizeof(u32)*10;
          652  +    aPage1[0] = BLOCK_PAGE1;
   681    653       sqlitePgTouch(aPage1);
   682    654       sqlitePgCommit(pDb->pPgr);
   683    655     }
   684         -  pDb->nContent = aPage1[2]/sizeof(u32);
   685         -  pDb->nAlloc = 0;
   686         -  rc = sqliteDbExpandContent(pDb, pDb->nContent);
          656  +  pDb->freeList = aPage[1];
          657  +  pDb->nTable = aPage[2];
          658  +  rc = sqliteDbExpandTableArray(pDb);
   687    659     if( rc!=SQLITE_OK ) goto open_err;
   688         -  rc = payloadRead(pDb, &aPage1[3], 0, aPage1[2], pDb->aContent);
          660  +  rc = payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
   689    661     sqlitePgUnref(aPage1);
   690    662     if( rc!=SQLITE_OK ) goto open_err;
   691    663     *ppDb = pDb;
   692    664     return SQLITE_OK;
   693    665   
   694    666   open_err:
   695    667     *ppDb = 0;
................................................................................
   740    712     u32 *aPage1;
   741    713     int rc;
   742    714     if( !pDb->inTransaction ){
   743    715       return SQLITE_OK;
   744    716     }
   745    717     rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   746    718     if( rc!=SQLITE_OK ) return rc;
   747         -  aPage1[2] = pDb->nContent*sizeof(u32);
   748         -  payloadWrite(pDb, 0, aPage1[2], pDb->aContent);
          719  +  aPage1[1] = pDb->freeList;
          720  +  aPage1[2] = pDb->nTable;
          721  +  payloadWrite(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
   749    722     sqlitePgUnref(aPage1);
   750    723     rc = sqlitePgCommit(pDb->pPgr);
   751    724     if( rc!=SQLITE_OK ) return rc;
   752    725     pDb->inTransaction = 0;
   753    726     return SQLITE_OK;
   754    727   }
   755    728   
................................................................................
   760    733   int sqliteDbRollback(Db *pDb){
   761    734     u32 *aPage1;
   762    735     if( !pDb->inTransaction ) return SQLITE_OK;
   763    736     rc = sqlitePgRollback(pDb->pPgr);
   764    737     if( rc!=SQLITE_OK ) return rc;
   765    738     rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
   766    739     if( rc!=SQLITE_OK ) return rc;
   767         -  pDb->nContent = SWB(aPage1[3]) + 2;
   768         -  if( sqliteDbExpandContent(pDb, pDb->nContent)!=SQLITE_OK ){
          740  +  pDb->freeList = aPage1[1];
          741  +  pDb->nTable = aPage1[2];
          742  +  if( sqliteDbExpandTableArray(pDb)!=SQLITE_OK ){
   769    743       return SQLITE_NOMEM;
   770    744     }
   771         -  payloadRead(pDb, &aPage1[3], 0, pDb->nContent*sizeof(u32), pDb->aContent);
          745  +  payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
          746  +  sqlitePgUnref(aPage1);
   772    747     pDb->inTransaction = 0;
   773    748     return SQLITE_OK;
   774    749   }
   775    750   
   776    751   /*
   777    752   ** Create a new table in the database.  Write the table number
   778    753   ** that is used to open a cursor into that table into *pTblno.
   779    754   */
   780    755   int sqliteDbCreateTable(Db *pDb, int *pTblno){
   781         -  u32 *pPage;
          756  +  u32 *aPage;
   782    757     u32 pgno;
   783    758     int rc;
   784    759     int swTblno;
   785    760     int i;
   786    761   
   787         -  rc = allocPage(pDb, &pgno, &pPage);
          762  +  rc = allocPage(pDb, &pgno, &aPage);
   788    763     if( rc!=SQLITE_OK ){
   789    764       return rc;
   790    765     }
   791    766     tblno = -1;
   792         -  for(i=2; i<pDb->nContent; i++){
   793         -    if( pDb->aContent[i]==0 ){
   794         -      tblno = i - 2;
          767  +  for(i=0; i<pDb->nTable; i++){
          768  +    if( pDb->aTable[i]==0 ){
          769  +      tblno = i;
   795    770         break;
   796    771       }
   797    772     }
   798    773     if( tblno<0 ){
   799         -    tblno = pDb->aContent[1];
          774  +    pDb->nTable++;
          775  +    rc = sqliteExpandTableArray(pDb);
          776  +    if( rc!=SQLITE_OK ){
          777  +      return rc;
          778  +    }
   800    779     }
   801         -  if( tblno+2 >= pDb->nContent ){
   802         -    sqliteDbExpandContent(pDb, tblno+2);
   803         -  }
   804         -  if( pDb->aContent==0 ){
   805         -    rc = SQLITE_NOMEM;
   806         -  }else{
   807         -    pDb->aContent[tblno+2] = pgno;
   808         -    pPage[0] = SWB(BLOCK_MAGIC | BLOCK_LEAF);
   809         -    memset(&pPage[1], 0, SQLITE_PAGE_SIZE - sizeof(u32));
   810         -    sqlitePgTouch(pPage);
   811         -  }
   812         -  sqlitePgUnref(pPage);
          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);
   813    785     return rc;
   814    786   }
   815    787   
   816    788   /*
   817    789   ** Recursively add a page to the free list
   818    790   */
   819    791   static int sqliteDbDropPage(Db *pDb, u32 pgno){
   820    792     u32 *aPage;
   821    793     int rc;
   822    794   
   823    795     rc = sqlitePgGet(pDb->pPgr, pgno, (void**)&aPage);
   824    796     if( rc!=SQLITE_OK ) return rc;
   825    797     switch(  aPage[0] ){
   826         -    case BLOCK_MAGIC | BLOCK_INDEX: {
          798  +    case BLOCK_INDEX: {
   827    799         int n, i;
   828    800         n = aPage[2];
   829    801         for(i=0; i<n; i++){
   830         -        u32 subpgno = aPage[4+i*2];
          802  +        u32 subpgno = aPage[3 + i*2];
   831    803           if( subpgno>0 ) sqliteDbDropPage(pDb, subpgno);
   832    804         }
   833    805         freePage(pDb, pgno, aPage);
   834    806         break;
   835    807       }
   836         -    case BLOCK_MAGIC | BLOCK_LEAF: {
          808  +    case BLOCK_LEAF: {
   837    809         int i = 2;
   838    810         while( i<U32_PER_PAGE ){
   839    811           int entrySize = aPage[i];
   840    812           if( entrySize==0 ) break;
   841         -        payloadFree(pDb, &aPage[i+4], 0, aPage[i+2]+aPage[i+3]);
          813  +        payloadResize(pDb, &aPage[i+4], aPage[i+2]+aPage[i+3], 0);
   842    814           i += entrySize;
   843    815         }
   844    816         freePage(pDb, pgno, aPage);
   845    817         break;
   846    818       }
   847    819       default: {
   848    820         /* Do nothing */
................................................................................
   870    842   */
   871    843   static int sqliteDbDropTable(Db *pDb, int tblno){
   872    844     DbCursor *pCur;
   873    845     u32 pgno;
   874    846   
   875    847     /* Find the root page for the table to be dropped.
   876    848     */
   877         -  if( pDb->aContent==0 ){
          849  +  if( pDb->aTable==0 ){
   878    850       return SQLITE_NOMEM;
   879    851     }
   880         -  if( tblno<0 || tblno+2>=pDb->nContent || pDb->aContent[tblno+2]==0 ){
          852  +  if( tblno<0 || tblno>=pDb->nTable || pDb->aTable[tblno]==0 ){
   881    853       return SQLITE_NOTFOUND;
   882    854     }
   883         -  pgno = pDb->aContent[tblno+2];
   884         -  pDb->aContent[tblno+2] = 0;
          855  +  pgno = pDb->aTable[tblno];
          856  +  pDb->aTable[tblno] = 0;
          857  +  if( tblno==pDb->nTable-1 ){
          858  +    pDb->nTable--;
          859  +  }
   885    860   
   886    861     /* Reset any cursors pointing to the table that is about to
   887    862     ** be dropped */
   888    863     for(pCur=pDb->pCursor; pCur; pCur=pCur->pNext){
   889    864       if( pCur->rootPgno==pgno ){
   890    865         sqliteDbResetCursor(pCur, 0);
   891    866       }
................................................................................
   902    877   */
   903    878   int sqliteDbCursorOpen(Db *pDb, int tblno, DbCursor **ppCur){
   904    879     u32 pgno;
   905    880     DbCursor *pCur;
   906    881   
   907    882     /* Translate the table number into a page number
   908    883     */
   909         -  if( pDb->aContent==0 ){
          884  +  if( pDb->aTable==0 ){
   910    885       *ppCur = 0;
   911    886       return SQLITE_NOMEM;
   912    887     }
   913         -  if( tblno<0 || tblno+2>=pDb->nContent || pDb->aContent[tblno+2]==0 ){
          888  +  if( tblno<0 || tblno>=pDb->nContent || pDb->aTable[tblno]==0 ){
   914    889       *ppCur = 0;
   915    890       return SQLITE_NOTFOUND;
   916    891     }
   917         -  pgno = SWB(pDb->aContent[tblno+2]);
          892  +  pgno = pDb->aTable[tblno];
   918    893     
   919    894     /* Allocate the cursor
   920    895     */
   921    896     pCur = sqliteMalloc( sizeof(*pCur) );
   922    897     pCur->pgno = pgno;
   923    898     pCur->pDb = pDb;
   924    899     pCur->pNext = pDb->pCursor;
................................................................................
   961    936     if( pCur->nLevel > i+1 ){
   962    937       sqliteDbResetCursor(pCur, i+1);
   963    938     }
   964    939     assert( pCur->nLevel==i+1 );
   965    940     while( rc < 0 ){
   966    941       u32 *aPage = pCur->aLevel[i].aPage;
   967    942       assert( aPage!=0 );
   968         -    switch( SWB(aPage[0]) ){
   969         -      case BLOCK_LEAF | BLOCK_MAGIC: {
   970         -        if( aPage[1]!=0 ){
   971         -          pCur->aLevel[i].idx = 1;
          943  +    switch( aPage[0] ){
          944  +      case BLOCK_LEAF: {
          945  +        if( aPage[2]!=0 ){
          946  +          pCur->aLevel[i].idx = 2;
   972    947             pCur->onEntry = 1;
   973    948           }else{
   974    949             sqliteDbResetCursor(pCur, 1);
   975    950           }
   976    951           rc = SQLITE_OK;
   977    952           break;
   978    953         }
   979         -      case BLOCK_INDEX | BLOCK_MAGIC: {
   980         -        int n = SWB(aPage[2]);
   981         -        if( n<2 || n>=((SQLITE_PAGE_SIZE/sizeof(u32))-3)/2 ){
          954  +      case BLOCK_INDEX: {
          955  +        int n = aPage[2];
          956  +        if( n<2 || n>=((U32_PER_PAGE - 3)/2) ){
   982    957             sqliteDbResetCur(pCur, 1);
   983    958             rc = SQLITE_CORRUPT;
   984    959             break;
   985    960           }
   986    961           pCur->nLevel++;
   987    962           i++;
   988         -        pCur->aLevel[i].pgno = SWB(aPage[4]);
          963  +        pCur->aLevel[i].pgno = aPage[3];
   989    964           rc = sqlitePgGet(pCur->pDb->pPgr, pCur->aLevel[i].pgno,
   990    965                       &pCur->aLevel[i].aPage);
   991    966           if( rc != SQLITE_OK ){
   992    967             sqliteDbResetCursor(pCur, 1);
   993    968           }else{
   994    969             rc = -1;
   995    970           }
................................................................................
   999    974           sqliteDbResetCursor(pCur, 1);
  1000    975           rc = SQLITE_CORRUPT;
  1001    976         }
  1002    977       }
  1003    978     }
  1004    979     return rc;
  1005    980   }
          981  +
          982  +################
  1006    983   
  1007    984   /*
  1008    985   ** Move the cursor to the first entry in the table.
  1009    986   */
  1010    987   int sqliteDbCursorFirst(DbCursor *pCur){
  1011    988     if( pCur->nLevel==0 ){
  1012    989       int rc;

Changes to src/db.h.

    17     17   ** Boston, MA  02111-1307, USA.
    18     18   **
    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24         -** $Id: db.h,v 1.4 2001/01/29 01:27:20 drh Exp $
           24  +** $Id: db.h,v 1.5 2001/01/31 13:28:09 drh Exp $
    25     25   */
    26     26   
    27     27   typedef struct Db Db;
    28     28   typedef struct DbCursor DbCursor;
    29     29   
    30     30   int sqliteDbOpen(const char *filename, Db**);
    31     31   int sqliteDbClose(Db*);
................................................................................
    43     43   int sqliteDbCursorNext(DbCursor*);
    44     44   int sqliteDbCursorDatasize(DbCursor*);
    45     45   int sqliteDbCursorKeysize(DbCursor*);
    46     46   int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf);
    47     47   int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf);
    48     48   int sqliteDbCursorWrite(DbCursor*, int amt, int offset, const void *buf);
    49     49   
    50         -int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createSize);
           50  +int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createFlag);
    51     51   int sqliteDbCursorResize(DbCursor*, int nData);

Changes to src/printf.c.

    42     42   **
    43     43   **      +  When compiled using GCC on a SPARC, this version of printf is
    44     44   **         faster than the library printf for SUN OS 4.1.
    45     45   **
    46     46   **      +  All functions are fully reentrant.
    47     47   **
    48     48   */
    49         -#include <ctype.h>
    50     49   #include "sqliteInt.h"
    51     50   
    52     51   /*
    53     52   ** Undefine COMPATIBILITY to make some slight changes in the way things
    54     53   ** work.  I think the changes are an improvement, but they are not
    55     54   ** backwards compatible.
    56     55   */
................................................................................
   258    257         width = va_arg(ap,int);
   259    258         if( width<0 ){
   260    259           flag_leftjustify = 1;
   261    260           width = -width;
   262    261         }
   263    262         c = *++fmt;
   264    263       }else{
   265         -      while( isdigit(c) ){
          264  +      while( c>='0' && c<='9' ){
   266    265           width = width*10 + c - '0';
   267    266           c = *++fmt;
   268    267         }
   269    268       }
   270    269       if( width > etBUFSIZE-10 ){
   271    270         width = etBUFSIZE-10;
   272    271       }
................................................................................
   278    277           precision = va_arg(ap,int);
   279    278   #ifndef etCOMPATIBILITY
   280    279           /* This is sensible, but SUN OS 4.1 doesn't do it. */
   281    280           if( precision<0 ) precision = -precision;
   282    281   #endif
   283    282           c = *++fmt;
   284    283         }else{
   285         -        while( isdigit(c) ){
          284  +        while( c>='0' && c<='9' ){
   286    285             precision = precision*10 + c - '0';
   287    286             c = *++fmt;
   288    287           }
   289    288         }
   290    289         /* Limit the precision to prevent overflowing buf[] during conversion */
   291    290         if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
   292    291       }else{

Changes to src/random.c.

    23     23   *************************************************************************
    24     24   ** This file contains code to implement a pseudo-random number
    25     25   ** generator (PRNG) for SQLite.
    26     26   **
    27     27   ** Random numbers are used by some of the database backends in order
    28     28   ** to generate random integer keys for tables or random filenames.
    29     29   **
    30         -** $Id: random.c,v 1.1 2001/01/13 14:34:07 drh Exp $
           30  +** $Id: random.c,v 1.2 2001/01/31 13:28:09 drh Exp $
    31     31   */
    32     32   #include "sqliteInt.h"
    33         -
           33  +#include <time.h>
    34     34   
    35     35   /*
    36     36   ** Get a single 8-bit random value from the RC4 PRNG.
    37     37   */
    38     38   int sqliteRandomByte(void){
    39     39     int t;
    40     40   

Changes to src/tclsqlite.c.

    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** A TCL Interface to SQLite
    25     25   **
    26         -** $Id: tclsqlite.c,v 1.12 2000/10/19 14:59:27 drh Exp $
           26  +** $Id: tclsqlite.c,v 1.13 2001/01/31 13:28:09 drh Exp $
    27     27   */
    28     28   #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
    29     29   
    30     30   #include "sqlite.h"
    31         -#include <tcl.h>
           31  +#include "tcl.h"
    32     32   #include <stdlib.h>
    33     33   #include <string.h>
    34     34   
    35     35   /*
    36     36   ** There is one instance of this structure for each SQLite database
    37     37   ** that has been opened by the SQLite TCL interface.
    38     38   */

Changes to test/dbbe.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is exercising the code in dbbe.c.
    25     25   #
    26         -# $Id: dbbe.test,v 1.4 2000/10/16 22:06:43 drh Exp $
           26  +# $Id: dbbe.test,v 1.5 2001/01/31 13:28:09 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Try to open a database that does not exist.
    32     32   #
    33     33   do_test dbbe-1.1 {
    34     34     catch {db close}
    35         -  file delete -force testdb
           35  +  forcedelete testdb
    36     36     set v [catch {sqlite db testdb 0444} msg]
    37     37     lappend v $msg
    38     38   } {1 {can't find directory "testdb"}}
    39     39   do_test dbbe-1.2 {
    40     40     catch {db close}
    41         -  file delete -force testdb
           41  +  forcedelete testdb
    42     42     set v [catch {sqlite db testdb/dummy 0666} msg]
    43     43     lappend v $msg
    44     44   } {1 {can't find or create directory "testdb/dummy"}}
    45     45   
    46     46   # Try to open a database for writing in a directory that
    47     47   # doesn't exist but for which the parent directory does
    48     48   # exist.  This should work!
    49     49   #
    50     50   do_test dbbe-1.3 {
    51     51     catch {db close}
    52         -  file delete -force testdb
           52  +  forcedelete testdb
    53     53     set v [catch {sqlite db testdb 0666} msg]
    54     54     lappend v $msg
    55     55   } {0 {}}
    56     56   
    57     57   # Try to open a file instead of a directory.
    58     58   #
    59     59   do_test dbbe-1.4 {
    60     60     catch {db close}
    61         -  file delete -force testdb
           61  +  forcedelete testdb
    62     62     set fd [open testdb w]
    63     63     puts $fd hi!
    64     64     close $fd
    65     65     set v [catch {sqlite db testdb 0666} msg]
    66     66     lappend v $msg
    67     67   } {1 {not a directory: "testdb"}}
    68     68   
    69     69   # Access permission denied on the directory.
    70     70   #
    71     71   do_test dbbe-1.5 {
    72     72     catch {db close}
    73         -  file delete -force testdb
           73  +  forcedelete testdb
    74     74     file mkdir testdb
    75     75     file attributes testdb -permissions 0
    76     76     set v [catch {sqlite db testdb 0666} msg]
    77     77     lappend v $msg
    78     78   } {1 {access permission denied}}
    79     79   
    80     80   # Access permission denied on the master file
    81     81   #
    82     82   do_test dbbe-1.6 {
    83     83     catch {db close}
    84         -  file delete -force testdb
           84  +  forcedelete testdb
    85     85     sqlite db testdb 0666
    86     86     execsql {CREATE TABLE t1(x int)}
    87     87     db close
    88     88     file attributes testdb/sqlite_master.tbl -permission 0444
    89     89     set v [catch {sqlite db testdb 0666} msg]
    90     90     lappend v $msg
    91     91   } {1 {access permission denied for testdb/sqlite_master.tbl}}
    92     92   do_test dbbe-1.6b {
    93     93     catch {db close}
    94         -  file delete -force testdb
           94  +  forcedelete testdb
    95     95     sqlite db testdb 0666
    96     96     execsql {CREATE TABLE t1(x int)}
    97     97     db close
    98     98     file attributes testdb/sqlite_master.tbl -permission 0444
    99     99     set v [catch {sqlite db testdb 0444} msg]
   100    100     lappend v $msg
   101    101   } {0 {}}
   102    102   
   103    103   # Make sure a table can be accessed by either uppercase or lowercase
   104    104   # names
   105    105   #
   106    106   do_test dbbe-2.1 {
   107    107     catch {db close}
   108         -  file delete -force testdb
          108  +  forcedelete testdb
   109    109     sqlite db testdb 0666
   110    110     execsql {
   111    111       CREATE TABLE t1(x int);
   112    112       INSERT INTO t1 VALUES(1);
   113    113     }
   114    114     db close
   115    115     sqlite db testdb 0444
................................................................................
   119    119     lappend r [execsql {SELECT * FROM t1}]
   120    120   } {1 1}
   121    121   
   122    122   # Try to change a table after opening the database readonly
   123    123   #
   124    124   do_test dbbe-3.1 {
   125    125     catch {db close}
   126         -  file delete -force testdb
          126  +  forcedelete testdb
   127    127     sqlite db testdb 0666
   128    128     execsql {CREATE TABLE t1(x int)}
   129    129     db close
   130    130     sqlite db testdb 0444
   131    131     set v [catch {execsql {INSERT INTO t1 VALUES(1)}} msg]
   132    132     lappend v $msg
   133    133   } {7 {table t1 is readonly}}
   134    134   
   135    135   
   136    136   finish_test

Changes to test/tester.tcl.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements some common TCL routines used for regression
    24     24   # testing the SQLite library
    25     25   #
    26         -# $Id: tester.tcl,v 1.9 2001/01/22 00:31:53 drh Exp $
           26  +# $Id: tester.tcl,v 1.10 2001/01/31 13:28:09 drh Exp $
    27     27   
    28     28   # Create a test database
    29     29   #
    30     30   if {![info exists dbprefix]} {
    31     31     if {[info exists env(SQLITE_PREFIX)]} {
    32     32       set dbprefix $env(SQLITE_PREFIX):
    33     33     } else {
    34     34       set dbprefix "gdbm:"
    35     35     }
    36     36   }
    37     37   switch $dbprefix {
    38     38     gdbm: {
    39         -   file delete -force testdb
           39  +   if {[catch {file delete -force testdb}]} {
           40  +     exec rm -rf testdb
           41  +   }
    40     42      file mkdir testdb
    41     43     }
    42     44     memory: {
    43     45      # do nothing
    44     46     }
    45     47   }
    46     48   sqlite db ${dbprefix}testdb
................................................................................
   151    153     db eval $sql data {
   152    154       foreach f $data(*) {
   153    155         lappend result $f $data($f)
   154    156       }
   155    157     }
   156    158     return $result
   157    159   }
          160  +
          161  +# Delete a file or directory
          162  +#
          163  +proc forcedelete {filename} {
          164  +  if {[catch {file delete -force $filename}]} {
          165  +    exec rm -rf $filename
          166  +  }
          167  +}

Changes to www/crosscompile.tcl.

     1      1   #
     2      2   # Run this Tcl script to generate the crosscompile.html file.
     3      3   #
     4         -set rcsid {$Id: crosscompile.tcl,v 1.3 2000/10/11 19:28:53 drh Exp $}
            4  +set rcsid {$Id: crosscompile.tcl,v 1.4 2001/01/31 13:28:09 drh Exp $}
     5      5   
     6      6   puts {<html>
     7      7   <head>
     8      8     <title>Notes On How To Compile SQLite Using The MinGW Cross-Compiler</title>
     9      9   </head>
    10     10   <body bgcolor=white>
    11     11   <h1 align=center>
................................................................................
   144    144   
   145    145   <blockquote><pre>
   146    146   cat &gt;&gt;systems.h &lt;&lt;\END
   147    147   #ifdef NO_LOCKS
   148    148   #undef  UNLOCK_FILE
   149    149   #define UNLOCK_FILE(x)
   150    150   #undef  READLOCK_FILE
   151         -#define READLOCK_FILE(x)
          151  +#define READLOCK_FILE(x)  lock_val=0;
   152    152   #undef  WRITELOCK_FILE
   153         -#define WRITELOCK_FILE(x)
          153  +#define WRITELOCK_FILE(x) lock_val=0;
   154    154   #endif
   155    155   END
   156    156   </pre></blockquote>
   157    157   
   158    158   <p>Then manually build the GDBM library with the extra
   159    159   "NO_LOCKS" define as follows:</p>
   160    160   <blockquote><pre>