mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
:-) (CVS 218)
FossilOrigin-Name: 523d52dfa6ae3028cbcc88d406501f3ebb6cbd2d
This commit is contained in:
20
manifest
20
manifest
@@ -1,5 +1,5 @@
|
||||
C :-)\s(CVS\s217)
|
||||
D 2001-05-15T00:39:25
|
||||
C :-)\s(CVS\s218)
|
||||
D 2001-05-21T13:45:10
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in acef0f0275a5ca8e68bda165f7f05d810a207664
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
@@ -12,7 +12,7 @@ F notes/notes1.txt b7c0812b704a022e88c621146ae50955c923d464
|
||||
F notes/notes2.txt 49b4d7ba35f183feb1fb098a27272b82f5c76eca
|
||||
F notes/notes3.txt cd5e7bd2167d7ef89b1077abdfa68f0af6337744
|
||||
F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4
|
||||
F src/btree.c f6d724fccaf108c4452dba6589e6027ba8f3e88a
|
||||
F src/btree.c bc1525234a8b169cae6f903f9cfacbcf971be942
|
||||
F src/btree.h f21c240d0c95f93e2a128106d04a6c448ed0eb94
|
||||
F src/build.c 4f6a2d551c56342cd4a0420654835be3ad179651
|
||||
F src/dbbe.c b18259f99d87240cbe751021cf14dd3aa83a48af
|
||||
@@ -31,7 +31,7 @@ F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
|
||||
F src/expr.c c4c24c3af1eba094a816522eb0e085bed518ee16
|
||||
F src/insert.c aa528e20a787af85432a61daaea6df394bd251d7
|
||||
F src/main.c 0a13c7a2beb8ce36aee43daf8c95989b200727a7
|
||||
F src/pager.c 4081e3e9765c272554e22d1dcec0647ac71ea706
|
||||
F src/pager.c e45946aaf080aed251653f21667d62c89e539a97
|
||||
F src/pager.h ed12ac3ddebd3afe61a0ed4bf530e7846d578e46
|
||||
F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
@@ -64,7 +64,7 @@ F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
|
||||
F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a
|
||||
F test/main.test da635f9e078cd21ddf074e727381a715064489ff
|
||||
F test/malloc.test 3daa97f6a9577d8f4c6e468b274333af19ce5861
|
||||
F test/pager.test 3416a155c2dc3b1b3c07d4bb0192cbb15b76a90c
|
||||
F test/pager.test c1eb25faa0938f803d1e6eb5201e5e976ea88256
|
||||
F test/printf.test 4c71871e1a75a2dacb673945fc13ddb30168798f
|
||||
F test/rowid.test 128453599def7435e988216f7fe89c7450b8a9a3
|
||||
F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f
|
||||
@@ -99,14 +99,14 @@ F www/changes.tcl 822b425cc50cb8e21563dd1aa0e4b79cf780f3dc
|
||||
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||
F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9
|
||||
F www/index.tcl 553a41c4157fe411465aefe391bec5687027e73f
|
||||
F www/lang.tcl 7fec414487ebee2cbb17c90addf5a026cd10396a
|
||||
F www/index.tcl 199abaf346d5fed6cf5b462a327faae39fb117b9
|
||||
F www/lang.tcl 0969ba9f13b3555e54ccdb8ec462dee2de0bf223
|
||||
F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
|
||||
F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P c3e521190f02120a34f1e9244fe1ea3a975a6caa
|
||||
R d3ffc66c90d6f5774a5954932275df58
|
||||
P ee6760fb62e81af95796c0fcf1e65e5dc0701194
|
||||
R 6bf7ed657f22039e86c99aa04cca003e
|
||||
U drh
|
||||
Z 0f43bc31472b172caca9953860c2e8b6
|
||||
Z 4c32ca5182d7191fa6afdab861fed35d
|
||||
|
@@ -1 +1 @@
|
||||
ee6760fb62e81af95796c0fcf1e65e5dc0701194
|
||||
523d52dfa6ae3028cbcc88d406501f3ebb6cbd2d
|
153
src/btree.c
153
src/btree.c
@@ -21,7 +21,7 @@
|
||||
** http://www.hwaci.com/drh/
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.5 2001/05/15 00:39:25 drh Exp $
|
||||
** $Id: btree.c,v 1.6 2001/05/21 13:45:10 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@@ -39,8 +39,8 @@
|
||||
** database entry. If the entry contains more data than this, the
|
||||
** extra goes onto overflow pages.
|
||||
*/
|
||||
#define MX_LOCAL_PAYLOAD ((SQLITE_PAGE_SIZE-sizeof(PageHdr)-4*sizeof(Cell))/4)
|
||||
|
||||
#define MX_LOCAL_PAYLOAD \
|
||||
((SQLITE_PAGE_SIZE-sizeof(PageHdr)-4*(sizeof(Cell)+sizeof(Pgno)))/4)
|
||||
|
||||
/*
|
||||
** The in-memory image of a disk page has the auxiliary information appended
|
||||
@@ -54,9 +54,9 @@
|
||||
*/
|
||||
#define OVERFLOW_SIZE (SQLITE_PAGE_SIZE-sizeof(Pgno))
|
||||
|
||||
|
||||
/*
|
||||
** Primitive data types. u32 must be 4 bytes and u16 must be 2 bytes.
|
||||
** Change these typedefs when porting to new architectures.
|
||||
*/
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short int u16;
|
||||
@@ -74,10 +74,12 @@ typedef struct OverflowPage OverflowPage;
|
||||
/*
|
||||
** All structures on a database page are aligned to 4-byte boundries.
|
||||
** This routine rounds up a number of bytes to the next multiple of 4.
|
||||
**
|
||||
** This might need to change for computer architectures that require
|
||||
** and 8-byte alignment boundry for structures.
|
||||
*/
|
||||
#define ROUNDUP(X) ((X+3) & ~3)
|
||||
|
||||
|
||||
/*
|
||||
** The first pages of the database file contains some additional
|
||||
** information used for housekeeping and sanity checking. Otherwise,
|
||||
@@ -92,7 +94,6 @@ struct Page1Header {
|
||||
#define MAGIC_1 0x7264dc61
|
||||
#define MAGIC_2 0x54e55d9e
|
||||
|
||||
|
||||
/*
|
||||
** Each database page has a header as follows:
|
||||
**
|
||||
@@ -102,17 +103,30 @@ struct Page1Header {
|
||||
** first_free Index of first free block
|
||||
**
|
||||
** MemPage.pStart always points to the rightmost_pgno. First_free is
|
||||
** 0 if there is no free space on this page. Otherwise it points to
|
||||
** an area like this:
|
||||
** 0 if there is no free space on this page. Otherwise, first_free is
|
||||
** the index in MemPage.aPage[] of a FreeBlk structure that describes
|
||||
** the first block of free space. All free space is defined by a linked
|
||||
** list of FreeBlk structures.
|
||||
**
|
||||
** nByte Number of free bytes in this block
|
||||
** next_free Next free block or 0 if this is the end
|
||||
** Data is stored in a linked list of Cell structures. First_cell is
|
||||
** the index into MemPage.aPage[] of the first cell on the page. The
|
||||
** Cells are kept in sorted order.
|
||||
*/
|
||||
struct PageHdr {
|
||||
Pgno pgno; /* Child page that comes after all cells on this page */
|
||||
u16 firstCell; /* Index in MemPage.aPage[] of the first cell */
|
||||
u16 firstFree; /* Index in MemPage.aPage[] of the first free block */
|
||||
};
|
||||
|
||||
/*
|
||||
** Data on a database page is stored as a linked list of Cell structures.
|
||||
** Both the key and the data are stored in aData[]. The key always comes
|
||||
** first. The aData[] field grows as necessary to hold the key and data,
|
||||
** up to a maximum of MX_LOCAL_PAYLOAD bytes. If the size of the key and
|
||||
** data combined exceeds MX_LOCAL_PAYLOAD bytes, then the 4 bytes beginning
|
||||
** at Cell.aData[MX_LOCAL_PAYLOAD] are the page number of the first overflow
|
||||
** page.
|
||||
*/
|
||||
struct Cell {
|
||||
Pgno pgno; /* Child page that comes before this cell */
|
||||
u16 nKey; /* Number of bytes in the key */
|
||||
@@ -120,10 +134,28 @@ struct Cell {
|
||||
u32 nData; /* Number of bytes of data */
|
||||
char aData[4]; /* Key and data */
|
||||
};
|
||||
|
||||
/*
|
||||
** Free space on a page is remembered using a linked list of the FreeBlk
|
||||
** structures. Space on a database page is allocated in increments of
|
||||
** at least 4 bytes and is always aligned to a 4-byte boundry.
|
||||
*/
|
||||
struct FreeBlk {
|
||||
u16 iSize; /* Number of u32-sized slots in the block of free space */
|
||||
u16 iNext; /* Index in MemPage.aPage[] of the next free block */
|
||||
};
|
||||
|
||||
/*
|
||||
** When the key and data for a single entry in the BTree will not fit in
|
||||
** the MX_LOACAL_PAYLOAD bytes of space available on the database page,
|
||||
** then all extra data is written to a linked list of overflow pages.
|
||||
** Each overflow page is an instance of the following structure.
|
||||
**
|
||||
** Unused pages in the database are also represented by instances of
|
||||
** the OverflowPage structure. The Page1Header.freeList field is the
|
||||
** page number of the first page in a linked list of unused database
|
||||
** pages.
|
||||
*/
|
||||
struct OverflowPage {
|
||||
Pgno next;
|
||||
char aData[SQLITE_PAGE_SIZE-sizeof(Pgno)];
|
||||
@@ -132,22 +164,29 @@ struct OverflowPage {
|
||||
/*
|
||||
** For every page in the database file, an instance of the following structure
|
||||
** is stored in memory. The aPage[] array contains the data obtained from
|
||||
** the disk. The rest is auxiliary data that held in memory only.
|
||||
** the disk. The rest is auxiliary data that held in memory only. The
|
||||
** auxiliary data is only valid for regular database pages - the auxiliary
|
||||
** data is meaningless for overflow pages and pages on the freelist.
|
||||
**
|
||||
** Of particular interest in the auxiliary data is the aCell[] entry. Each
|
||||
** aCell[] entry is a pointer to a Cell structure in aPage[]. The cells
|
||||
** put in this array so that they can be accessed in constant time, rather
|
||||
** than in linear time which would be needed if we walked the linked list.
|
||||
*/
|
||||
struct MemPage {
|
||||
char aPage[SQLITE_PAGE_SIZE]; /* Page data stored on disk */
|
||||
unsigned char isInit; /* True if sequel is initialized */
|
||||
unsigned char isInit; /* True if auxiliary data is initialized */
|
||||
unsigned char validUp; /* True if MemPage.up is valid */
|
||||
unsigned char validLeft; /* True if MemPage.left is valid */
|
||||
unsigned char validRight; /* True if MemPage.right is valid */
|
||||
Pgno up; /* The parent page. 0 means this is the root */
|
||||
Pgno left; /* Left sibling page. 0==none */
|
||||
Pgno right; /* Right sibling page. 0==none */
|
||||
int idxStart; /* Index in aPage[] of real data */
|
||||
PageHdr *pStart; /* Points to aPage[idxStart] */
|
||||
int nFree; /* Number of free bytes in aPage[] */
|
||||
int nCell; /* Number of entries on this page */
|
||||
u32 *aCell[MX_CELL]; /* All entires in sorted order */
|
||||
Pgno up; /* The parent page. 0 means this is the root */
|
||||
Pgno left; /* Left sibling page. 0==none */
|
||||
Pgno right; /* Right sibling page. 0==none */
|
||||
int idxStart; /* Index in aPage[] of real data */
|
||||
PageHdr *pStart; /* Points to aPage[idxStart] */
|
||||
int nFree; /* Number of free bytes in aPage[] */
|
||||
int nCell; /* Number of entries on this page */
|
||||
Cell *aCell[MX_CELL]; /* All data entires in sorted order */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -155,9 +194,9 @@ struct MemPage {
|
||||
*/
|
||||
struct Btree {
|
||||
Pager *pPager; /* The page cache */
|
||||
BtCursor *pCursor; /* All open cursors */
|
||||
BtCursor *pCursor; /* A list of all open cursors */
|
||||
MemPage *page1; /* First page of the database */
|
||||
int inTrans; /* True if a transaction is current */
|
||||
int inTrans; /* True if a transaction is in progress */
|
||||
};
|
||||
typedef Btree Bt;
|
||||
|
||||
@@ -213,7 +252,8 @@ static void defragmentPage(MemPage *pPage){
|
||||
** nByte bytes in size. (Actually, all allocations are rounded
|
||||
** up to the next even multiple of 4.) Return the index into
|
||||
** pPage->aPage[] of the first byte of the new allocation.
|
||||
** Or return 0 if there is not enough space.
|
||||
** Or return 0 if there is not enough free space on the page to
|
||||
** satisfy the allocation request.
|
||||
**
|
||||
** This routine will call defragmentPage if necessary to consolidate
|
||||
** free space.
|
||||
@@ -249,7 +289,10 @@ static int allocSpace(MemPage *pPage, int nByte){
|
||||
/*
|
||||
** Return a section of the MemPage.aPage[] to the freelist.
|
||||
** The first byte of the new free block is pPage->aPage[start]
|
||||
** and there are a told of size bytes to be freed.
|
||||
** and the size of the block is "size".
|
||||
**
|
||||
** Most of the effort here is involved in coalesing adjacent
|
||||
** free blocks into a single big free block.
|
||||
*/
|
||||
static void freeSpace(MemPage *pPage, int start, int size){
|
||||
int end = start + size;
|
||||
@@ -307,6 +350,7 @@ static int initPage(MemPage *pPage, Pgno pgnoThis, Pgno pgnoParent){
|
||||
idx = pPage->pStart->firstCell;
|
||||
while( idx!=0 ){
|
||||
if( idx>SQLITE_PAGE_SIZE-sizeof(Cell) ) goto page_format_error;
|
||||
if( idx<pPage->idxStart + sizeof(PageHeader) ) goto page_format_error;
|
||||
pCell = (Cell*)&pPage->aPage[idx];
|
||||
pPage->aCell[pPage->nCell++] = pCell;
|
||||
idx = pCell->iNext;
|
||||
@@ -315,6 +359,7 @@ static int initPage(MemPage *pPage, Pgno pgnoThis, Pgno pgnoParent){
|
||||
idx = pPage->pStart->firstFree;
|
||||
while( idx!=0 ){
|
||||
if( idx>SQLITE_PAGE_SIZE-sizeof(FreeBlk) ) goto page_format_error;
|
||||
if( idx<pPage->idxStart + sizeof(PageHeader) ) goto page_format_error;
|
||||
pFBlk = (FreeBlk*)&pPage->aPage[idx];
|
||||
pPage->nFree += pFBlk->iSize;
|
||||
if( pFBlk->iNext <= idx ) goto page_format_error;
|
||||
@@ -327,7 +372,11 @@ page_format_error:
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a new database
|
||||
** Open a new database.
|
||||
**
|
||||
** Actually, this routine just sets up the internal data structures
|
||||
** for accessing the database. We do not actually open the database
|
||||
** file until the first page is loaded.
|
||||
*/
|
||||
int sqliteBtreeOpen(const char *zFilename, int mode, Btree **ppBtree){
|
||||
Btree *pBt;
|
||||
@@ -362,6 +411,41 @@ int sqliteBtreeClose(Btree *pBt){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Get a reference to page1 of the database file. This will
|
||||
** also acquire a readlock on that file.
|
||||
**
|
||||
** SQLITE_OK is returned on success. If the file is not a
|
||||
** well-formed database file, then SQLITE_CORRUPT is returned.
|
||||
** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
|
||||
** is returned if we run out of memory. SQLITE_PROTOCOL is returned
|
||||
** if there is a locking protocol violation.
|
||||
*/
|
||||
static int lockBtree(Btree *pBt){
|
||||
int rc;
|
||||
if( pBt->page1 ) return SQLITE_OK;
|
||||
rc = sqlitepager_get(pBt->pPager, 1, &pBt->page1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
rc = initPage(pBt->page1, 1, 0);
|
||||
if( rc!=SQLITE_OK ) goto lock_failed;
|
||||
|
||||
/* Do some checking to help insure the file we opened really is
|
||||
** a valid database file.
|
||||
*/
|
||||
if( sqlitepager_pagecount(pBt->pPager)>0 ){
|
||||
Page1Header *pP1 = (Page1Header*)pBt->page1;
|
||||
if( pP1->magic1!=MAGIC_1 || pP1->magic2!=MAGIC_2 ){
|
||||
rc = SQLITE_CORRUPT;
|
||||
goto lock_failed;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
lock_failed:
|
||||
sqlitepager_unref(pBt->page1);
|
||||
pBt->page1 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Start a new transaction
|
||||
*/
|
||||
@@ -379,25 +463,6 @@ int sqliteBtreeBeginTrans(Btree *pBt){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Get a reference to page1 of the database file. This will
|
||||
** also acquire a readlock on that file.
|
||||
*/
|
||||
static int lockBtree(Btree *pBt){
|
||||
int rc;
|
||||
if( pBt->page1 ) return SQLITE_OK;
|
||||
rc = sqlitepager_get(pBt->pPager, 1, &pBt->page1);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
rc = initPage(pBt->page1, 1, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlitepager_unref(pBt->page1);
|
||||
pBt->page1 = 0;
|
||||
return rc;
|
||||
}
|
||||
/* Sanity checking on the database file format */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Remove the last reference to the database file. This will
|
||||
** remove the read lock.
|
||||
|
48
src/pager.c
48
src/pager.c
@@ -25,9 +25,9 @@
|
||||
**
|
||||
** The page cache is used to access a database file. The pager journals
|
||||
** all writes in order to support rollback. Locking is used to limit
|
||||
** access to one or more reader or on writer.
|
||||
** access to one or more reader or one writer.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.5 2001/04/28 16:52:42 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.6 2001/05/21 13:45:10 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@@ -56,13 +56,16 @@
|
||||
** threads can be reading or writing while one
|
||||
** process is writing.
|
||||
**
|
||||
** The page cache comes up in PCS_UNLOCK. The first time a
|
||||
** sqlite_page_get() occurs, the state transitions to PCS_READLOCK.
|
||||
** The page cache comes up in SQLITE_UNLOCK. The first time a
|
||||
** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
|
||||
** After all pages have been released using sqlite_page_unref(),
|
||||
** the state transitions back to PCS_UNLOCK. The first time
|
||||
** the state transitions back to SQLITE_UNLOCK. The first time
|
||||
** that sqlite_page_write() is called, the state transitions to
|
||||
** PCS_WRITELOCK. The sqlite_page_rollback() and sqlite_page_commit()
|
||||
** functions transition the state back to PCS_READLOCK.
|
||||
** SQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
|
||||
** called on an outstanding page which means that the pager must
|
||||
** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
|
||||
** The sqlite_page_rollback() and sqlite_page_commit() functions
|
||||
** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
|
||||
*/
|
||||
#define SQLITE_UNLOCK 0
|
||||
#define SQLITE_READLOCK 1
|
||||
@@ -96,7 +99,7 @@ struct PgHdr {
|
||||
|
||||
/*
|
||||
** How big to make the hash table used for locating in-memory pages
|
||||
** by page number.
|
||||
** by page number. Knuth says this should be a prime number.
|
||||
*/
|
||||
#define N_PG_HASH 101
|
||||
|
||||
@@ -336,8 +339,9 @@ static int pager_unwritelock(Pager *pPager){
|
||||
** file-type string for sanity checking. Then there is a single
|
||||
** Pgno number which is the number of pages in the database before
|
||||
** changes were made. The database is truncated to this size.
|
||||
** Next come zero or more page records which each page record
|
||||
** consists of a Pgno, SQLITE_PAGE_SIZE bytes of data.
|
||||
** Next come zero or more page records where each page record
|
||||
** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
|
||||
** the PageRecord structure for details.
|
||||
**
|
||||
** For playback, the pages have to be read from the journal in
|
||||
** reverse order and put back into the original database file.
|
||||
@@ -568,6 +572,12 @@ static void sqlitepager_ref(PgHdr *pPg){
|
||||
** A read lock is obtained for the first page acquired. The lock
|
||||
** is dropped when the last page is released.
|
||||
**
|
||||
** A _get works for any page number greater than 0. If the database
|
||||
** file is smaller than the requested page, then no actual disk
|
||||
** read occurs and the memory image of the page is initialized to
|
||||
** all zeros. The extra data appended to a page is always initialized
|
||||
** to zeros the first time a page is loaded into memory.
|
||||
**
|
||||
** The acquisition might fail for several reasons. In all cases,
|
||||
** an appropriate error code is returned and *ppPage is set to NULL.
|
||||
**
|
||||
@@ -727,8 +737,13 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
assert( pPg->pNextHash->pPrevHash==0 );
|
||||
pPg->pNextHash->pPrevHash = pPg;
|
||||
}
|
||||
pager_seek(pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
|
||||
pager_read(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
||||
if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
|
||||
if( pPager->dbSize<pgno ){
|
||||
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
|
||||
}else{
|
||||
pager_seek(pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
|
||||
pager_read(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
||||
}
|
||||
if( pPager->nExtra>0 ){
|
||||
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
|
||||
}
|
||||
@@ -749,8 +764,8 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
** See also sqlitepager_get(). The difference between this routine
|
||||
** and sqlitepager_get() is that _get() will go to the disk and read
|
||||
** in the page if the page is not already in cache. This routine
|
||||
** returns NULL if the page is not in cache and no disk I/O ever
|
||||
** occurs.
|
||||
** returns NULL if the page is not in cache of if a disk I/O has ever
|
||||
** happened.
|
||||
*/
|
||||
void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
|
||||
PgHdr *pPg;
|
||||
@@ -824,7 +839,7 @@ int sqlitepager_unref(void *pData){
|
||||
** The first time this routine is called, the pager creates a new
|
||||
** journal and acquires a write lock on the database. If the write
|
||||
** lock could not be acquired, this routine returns SQLITE_BUSY. The
|
||||
** calling routine must check for that routine and be careful not to
|
||||
** calling routine must check for that return value and be careful not to
|
||||
** change any page data until this routine returns SQLITE_OK.
|
||||
**
|
||||
** If the journal file could not be written because the disk is full,
|
||||
@@ -889,6 +904,9 @@ int sqlitepager_write(void *pData){
|
||||
}
|
||||
}
|
||||
pPg->inJournal = 1;
|
||||
if( pPager->dbSize<pPg->pgno ){
|
||||
pPager->dbSize = pPg->pgno;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is page cache subsystem.
|
||||
#
|
||||
# $Id: pager.test,v 1.3 2001/04/17 20:09:11 drh Exp $
|
||||
# $Id: pager.test,v 1.4 2001/05/21 13:45:10 drh Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@@ -75,7 +75,7 @@ do_test pager-2.3 {
|
||||
} {0}
|
||||
do_test pager-2.4 {
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
||||
do_test pager-2.5 {
|
||||
pager_pagecount $::p1
|
||||
} {0}
|
||||
@@ -103,7 +103,7 @@ do_test pager-2.12 {
|
||||
} {1}
|
||||
do_test pager-2.13 {
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 0 miss 2 ovfl 0}
|
||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 2 ovfl 0}
|
||||
do_test pager-2.14 {
|
||||
set v [catch {
|
||||
page_write $::g1 "Page-One"
|
||||
@@ -112,7 +112,7 @@ do_test pager-2.14 {
|
||||
} {0 {}}
|
||||
do_test pager-2.15 {
|
||||
pager_stats $::p1
|
||||
} {ref 1 page 1 max 10 size 0 state 2 err 0 hit 0 miss 2 ovfl 0}
|
||||
} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 0 miss 2 ovfl 0}
|
||||
do_test pager-2.16 {
|
||||
page_read $::g1
|
||||
} {Page-One}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this TCL script to generate HTML for the index.html file.
|
||||
#
|
||||
set rcsid {$Id: index.tcl,v 1.36 2001/04/05 16:49:44 drh Exp $}
|
||||
set rcsid {$Id: index.tcl,v 1.37 2001/05/21 13:45:10 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head><title>SQLite: An SQL Database Library Built Atop GDBM</title></head>
|
||||
@@ -69,7 +69,7 @@ only reached when <tt>malloc()</tt> fails.</p>
|
||||
But it only ignores case for 7-bit Latin characters.
|
||||
The case of 8-bit iso8859 characters or UTF-8 characters is
|
||||
signification. Hence, <b>'a' LIKE 'A'</b> returns
|
||||
TRUE but <b>'æ' LIKE 'Æ'</b>" returns FALSE.
|
||||
TRUE but <b>'æ' LIKE 'Æ'</b> returns FALSE.
|
||||
</p></li>
|
||||
</ul>
|
||||
|
||||
@@ -147,7 +147,7 @@ found <a href="crosscompile.html">here</a>.
|
||||
puts {<h2>Command-line Usage Example</h2>
|
||||
|
||||
<p>Download the source archive and compile the <b>sqlite</b>
|
||||
program as described above. The type:</p>
|
||||
program as described above. Then type:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
bash$ sqlite ~/newdb <i>Directory ~/newdb created automatically</i>
|
||||
|
16
www/lang.tcl
16
www/lang.tcl
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.7 2001/04/04 11:48:58 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.8 2001/05/21 13:45:10 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@@ -384,10 +384,16 @@ to the right contains the wildcards.}
|
||||
puts "A percent symbol [Operator %] in the right operand
|
||||
matches any sequence of zero or more characters on the left.
|
||||
An underscore [Operator _] on the right
|
||||
matches any single character on the left. The LIKE operator is
|
||||
matches any single character on the left."
|
||||
puts {The LIKE operator is
|
||||
not case sensitive and will match upper case characters on one
|
||||
side against lower case characters on the other.</p>"
|
||||
puts {
|
||||
side against lower case characters on the other.
|
||||
(A bug: SQLite only understands upper/lower case for 7-bit Latin
|
||||
characters. Hence the LIKE operator is case sensitive for
|
||||
8-bit iso8859 characters or UTF-8 characters. For example,
|
||||
the expression <b>'a' LIKE 'A'</b> is TRUE but
|
||||
<b>'æ' LIKE 'Æ'</b> is FALSE.)
|
||||
</p>
|
||||
|
||||
<p>The GLOB operator is similar to LIKE but uses the Unix
|
||||
file globbing syntax for its wildcards. Also, GLOB is case
|
||||
@@ -398,7 +404,7 @@ the NOT keyword to invert the sense of the test.</p>
|
||||
statement or one of the following special identifiers: "<b>ROWID</b>",
|
||||
"<b>OID</b>", or "<b>_ROWID_</b>".
|
||||
These special identifiers all describe the
|
||||
unique random integer key (the "row key") associated every every
|
||||
unique random integer key (the "row key") associated with every
|
||||
row of every table.
|
||||
The special identifiers only refer to the row key if the CREATE TABLE
|
||||
statement does not define a real column with the same name. Row keys
|
||||
|
Reference in New Issue
Block a user