1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-01 06:27:03 +03:00

Misc cleanup. Notes on compiling for Win95. (CVS 152)

FossilOrigin-Name: 3f0f1fa1fce794d1661c845f1a63a8d744892c25
This commit is contained in:
drh
2000-10-11 19:28:51 +00:00
parent d42b00f654
commit 7c68d60b6f
15 changed files with 4153 additions and 33 deletions

View File

@ -57,6 +57,7 @@ SRC = \
$(TOP)/src/build.c \
$(TOP)/src/dbbe.c \
$(TOP)/src/dbbe.h \
$(TOP)/src/dbbemem.c \
$(TOP)/src/delete.c \
$(TOP)/src/expr.c \
$(TOP)/src/insert.c \

View File

@ -1 +1 @@
1.0.9
1.0.10

3276
contrib/dlmalloc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,35 @@
C Version\s1.0.9\s(CVS\s493)
D 2000-10-09T22:30:00
C Misc\scleanup.\s\sNotes\son\scompiling\sfor\sWin95.\s(CVS\s152)
D 2000-10-11T19:28:51
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in f0b70aaa6717f9454c787dc74e5504c98ae7ea18
F Makefile.in faecea9b6419cec25030b4818c9b3f7f4163b3c1
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
F VERSION 1fe894c9b80001e9dbc3b40ef1f4f984c9b624f3
F VERSION 0302755bd219af2c39c53cc097caccb858798223
F configure 3dc1edb9dcf60215e31ff72b447935ab62211442 x
F configure.in d892ca33db7e88a055519ce2f36dcb11020e8fff
F contrib/dlmalloc.c 754f43cd3b225728017b2516a58103f4bc3f05ee
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
F src/build.c 4d90e9e94750ca80249fc7958c617021d8bb7a50
F src/dbbe.c 226daaf8c095ceb4aff48cad188dad90643f9867
F src/dbbe.h 6337132f904e72ecb28b07390021c241397e4cbf
F src/dbbemem.c eb3d79be7105bd80069815ee499c8e8682876378
F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065
F src/expr.c e8e350d7baa33bd9ed8701c159eaba5e912e0adb
F src/insert.c f146f149ad2422a1dc3bfa7a1651a25940f98958
F src/main.c 9a89579b40e498920f86e89878f52185457b9c2c
F src/main.c 03ca6d7601b40a3c6de95d7f8c6c817e8cca9fdf
F src/parse.y 5d199034de5d29ebedb42c1c51f34db4df40cbe5
F src/printf.c 534954b942046761e0860c30a9031fa9d803ca3c
F src/printf.c 6fc343f0c3537e2530a11ac164ce64ba171aebf8
F src/select.c d382e96c2221d08367cc87976f2b574537c9de97
F src/shell.c ef5d12129c824cb98238763e9e86ca1847e0c7bd
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 7a11f9d131e9657d11dee5c23dfe458da91de8e2
F src/sqliteInt.h b65fdecac7281aafb4c9ff3e79ea1b5546478385
F src/table.c 12f0165b47178b54a675d25ed373ee7e798d6ff0
F src/tclsqlite.c 7ccccae67fb36ed60ec98282953bf5dad0f9c16f
F src/table.c f08189678c806d8a74a70c156d7c27083760e028
F src/tclsqlite.c 44b08b47612a668caaf7c4ec32133b69d73ff78e
F src/tokenize.c 097bec5843d4a0fb4509e036fee93bac080c5e73
F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
F src/util.c 782f87af3c48c898631a2d5b7074437c899f6f13
F src/vdbe.c c0e3d29d2e13997d5664ade19ff2c8e2212945e3
F src/vdbe.h 6413cd0165ac62b0839fe3e077cb7c9f0b736295
F src/util.c 811e0ad47f842c16555aaf361b26dab7221c1a6c
F src/vdbe.c b8b0bc26d6543d5d33820809122bf0e7659e4663
F src/vdbe.h 8ca755f77eeaa93886d25188fd66129febfa16cf
F src/where.c 3dfad2ffd0aa994d5eceac88852f7189c8d1d3c8
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
@ -64,8 +66,8 @@ F www/arch.fig 4f246003b7da23bd63b8b0af0618afb4ee3055c8
F www/arch.png 8dae0766d42ed3de9ed013c1341a5792bcf633e6
F www/arch.tcl a40380c1fe0080c43e6cc5c20ed70731511b06be
F www/c_interface.tcl 03f5fe8f2da9713aa1748f7e4ce34a0c35926ac9
F www/changes.tcl 9f98c996ce4f60d082deab9b29c2d7f7981ea680
F www/crosscompile.tcl 19734ce7f18b16ff2ed8479412abf8aca56e1dcc
F www/changes.tcl fcd35239062ac03d6169506ae8ef19189979c8f1
F www/crosscompile.tcl bee79c34f6c3f162ec1c6f5294e79f73651d27ee
F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9
F www/index.tcl b19418d506f90968deef972bf1b427d98bdf13e0
F www/lang.tcl 9192e114b19987e630a41e879585b87006eb84a1
@ -74,7 +76,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
F www/tclsqlite.tcl ae101d5f7c07dcc59770e2a84aae09025fab2dad
F www/vdbe.tcl bcbfc33bcdd0ebad95eab31286adb9e1bc289520
P 15340d2bb34c4d7ab629f9fa2231c7f34a248db9
R 02bf6b83b2b17b70d381cfc976f772c2
P ebbb9e4a660e833efddb7ffea737135fff3bf2f5
R 0e3d2b823401c2dde691e21fb25d6652
U drh
Z 35d8208b4df3d6667977ea9f36f5d1b8
Z faddfef9a141ecc95fe77c48bb93186c

View File

@ -1 +1 @@
ebbb9e4a660e833efddb7ffea737135fff3bf2f5
3f0f1fa1fce794d1661c845f1a63a8d744892c25

766
src/dbbemem.c Normal file
View File

@ -0,0 +1,766 @@
/*
** Copyright (c) 1999, 2000 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public
** License as published by the Free Software Foundation; either
** version 2 of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public
** License along with this library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains code to implement the database backend (DBBE)
** for sqlite. The database backend is the interface between
** sqlite and the code that does the actually reading and writing
** of information to the disk.
**
** This file implements a backend that constructs a database in
** memory using hash tables. Nothing is ever read or written
** to disk. Everything is forgotten when the program exits.
**
** $Id: dbbemem.c,v 1.1 2000/10/11 19:28:52 drh Exp $
*/
#include "sqliteInt.h"
#include <time.h>
/*
** The following structure holds the current state of the RC4 algorithm.
** We use RC4 as a random number generator. Each call to RC4 gives
** a random 8-bit number.
**
** Nothing in this file or anywhere else in SQLite does any kind of
** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
** number generator) not as an encryption device.
*/
struct rc4 {
int i, j;
int s[256];
};
/*
** Key or data is stored as an instance of the following
*/
typedef struct datum {
void *dptr; /* The data */
int dsize; /* Number of bytes of data */
void *kptr; /* The key */
int ksize; /* Number of bytes of key */
datum *pHash; /* Next datum with the same hash */
}
/*
** Information about each open database table is an instance of this
** structure. There will only be one such structure for each
** table. If the VDBE opens the same table twice (as will happen
** for a self-join, for example) then two DbbeCursor structures are
** created but there is only a single BeFile structure with an
** nRef of 2.
*/
typedef struct BeFile BeFile;
struct BeFile {
char *zName; /* Name of the table */
BeFile *pNext, *pPrev; /* Next and previous on list of all tables */
BeFile *pHash; /* Next table with same hash on zName */
int nRef; /* Number of cursor that have this file open */
int delOnClose; /* Delete when the last cursor closes this file */
int nRec; /* Number of entries in the hash table */
int nHash; /* Number of slots in the hash table */
datum **aHash; /* The hash table */
};
/*
** The complete database is an instance of the following structure.
*/
struct Dbbe {
BeFile *pOpen; /* List of open tables */
int nTemp; /* Number of temporary files created */
FILE **apTemp; /* Space to hold temporary file pointers */
char **azTemp; /* Names of the temporary files */
struct rc4 rc4; /* The random number generator */
BeFile aHash[331]; /* Hash table of tables */
};
/*
** An cursor into a database file is an instance of the following structure.
** There can only be a single BeFile structure for each disk file, but
** there can be multiple DbbeCursor structures. Each DbbeCursor represents
** a cursor pointing to a particular part of the open BeFile. The
** BeFile.nRef field hold a count of the number of DbbeCursor structures
** associated with the same disk file.
*/
struct DbbeCursor {
Dbbe *pBe; /* The database of which this record is a part */
BeFile *pFile; /* The database file for this table */
datum *pRec; /* Most recently used key and data */
int h; /* Hash of pRec */
int needRewind; /* Next key should be the first */
int readPending; /* The fetch hasn't actually been done yet */
};
/*
** Initialize the RC4 PRNG. "seed" is a pointer to some random
** data used to initialize the PRNG.
*/
static void rc4init(struct rc4 *p, char *seed, int seedlen){
int i;
char k[256];
p->j = 0;
p->i = 0;
for(i=0; i<256; i++){
p->s[i] = i;
k[i] = seed[i%seedlen];
}
for(i=0; i<256; i++){
int t;
p->j = (p->j + p->s[i] + k[i]) & 0xff;
t = p->s[p->j];
p->s[p->j] = p->s[i];
p->s[i] = t;
}
}
/*
** Get a single 8-bit random value from the RC4 PRNG.
*/
static int rc4byte(struct rc4 *p){
int t;
p->i = (p->i + 1) & 0xff;
p->j = (p->j + p->s[p->i]) & 0xff;
t = p->s[p->i];
p->s[p->i] = p->s[p->j];
p->s[p->j] = t;
t = p->s[p->i] + p->s[p->j];
return t & 0xff;
}
/*
** This routine opens a new database. For the GDBM driver
** implemented here, the database name is the name of the directory
** containing all the files of the database.
**
** If successful, a pointer to the Dbbe structure is returned.
** If there are errors, an appropriate error message is left
** in *pzErrMsg and NULL is returned.
*/
Dbbe *sqliteDbbeOpen(
const char *zName, /* The name of the database */
int writeFlag, /* True if we will be writing to the database */
int createFlag, /* True to create database if it doesn't exist */
char **pzErrMsg /* Write error messages (if any) here */
){
Dbbe *pNew;
time_t now;
pNew = sqliteMalloc(sizeof(Dbbe));
if( pNew==0 ){
sqliteSetString(pzErrMsg, "out of memory", 0);
return 0;
}
pNew->pOpen = 0;
time(&now);
rc4init(&pNew->rc4, (char*)&now, sizeof(now));
return pNew;
}
/*
** Free all of the memory associated with a single BeFile structure.
** It is assumed that this BeFile structure has already been unlinked
** from its database.
*/
static void sqliteDbbeFreeFile(BeFile *pFile){
int i;
for(i=0; i<pFile->nHash; i++){
datum *pDatum, *pNextDatum;
for(pDatum = pFile->aHash[i]; pDatum; pDatum=pNextDatum){
pNextDatum = pDatum->pHash;
sqliteFree(pDatum->dptr);
sqliteFree(pDatum);
}
}
sqliteFree(pFile->zName);
sqliteFree(pFile->aHash);
memset(pFile, 0, sizeof(*pFile));
sqliteFree(pFile);
}
/*
** Completely shutdown the given database. Close all files. Free all memory.
*/
void sqliteDbbeClose(Dbbe *pBe){
BeFile *pFile, *pNext;
int i;
for(pFile=pBe->pOpen; pFile; pFile=pNext){
pNext = pFile->pNext;
sqliteDbbeFreeFile(pFile);
}
for(i=0; i<pBe->nTemp; i++){
if( pBe->apTemp[i]!=0 ){
unlink(pBe->azTemp[i]);
fclose(pBe->apTemp[i]);
sqliteFree(pBe->azTemp[i]);
pBe->apTemp[i] = 0;
pBe->azTemp[i] = 0;
break;
}
}
sqliteFree(pBe->azTemp);
sqliteFree(pBe->apTemp);
memset(pBe, 0, sizeof(*pBe));
sqliteFree(pBe);
}
/*
** Generate a random filename with the given prefix. The new filename
** is written into zBuf[]. The calling function must insure that
** zBuf[] is big enough to hold the prefix plus 20 or so extra
** characters.
**
** Very random names are chosen so that the chance of a
** collision with an existing filename is very very small.
*/
static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
int i, j;
static const char zRandomChars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
strcpy(zBuf, zPrefix);
j = strlen(zBuf);
for(i=0; i<15; i++){
int c = rc4byte(pRc4) % (sizeof(zRandomChars) - 1);
zBuf[j++] = zRandomChars[c];
}
zBuf[j] = 0;
}
/*
** Hash a NULL-terminated string.
*/
static int sqliteStrHash(const char *z){
int h = 0;
while( *z ){
h = (h<<3) ^ h ^ *(z++);
}
if( h<0 ) h = -h;
return h;
}
/*
** Locate a file in a database
*/
static BeFile *sqliteDbbeFindFile(Dbbe *pBe, const char *zFile){
int h;
BeFile *pFile;
h = sqliteStrHash(zFile) % (sizeof(pBe->aHash)/sizeof(pBe->aHash[0]));
for(pFile=pBe->aHash[h]; pFile; pFile=pFile->pHash){
if( strcmp(pFile->zName, zFile)==0 ) break;
}
return pFile;
}
/*
** Open a new table cursor. Write a pointer to the corresponding
** DbbeCursor structure into *ppCursr. Return an integer success
** code:
**
** SQLITE_OK It worked!
**
** SQLITE_NOMEM sqliteMalloc() failed
**
** SQLITE_PERM Attempt to access a file for which file
** access permission is denied
**
** SQLITE_BUSY Another thread or process is already using
** the corresponding file and has that file locked.
**
** SQLITE_READONLY The current thread already has this file open
** readonly but you are trying to open for writing.
** (This can happen if a SELECT callback tries to
** do an UPDATE or DELETE.)
**
** If zTable is 0 or "", then a temporary database file is created and
** a cursor to that temporary file is opened. The temporary file
** will be deleted from the disk when it is closed.
*/
int sqliteDbbeOpenCursor(
Dbbe *pBe, /* The database the table belongs to */
const char *zTable, /* The SQL name of the file to be opened */
int writeable, /* True to open for writing */
DbbeCursor **ppCursr /* Write the resulting table pointer here */
){
char *zFile; /* Name of the table file */
DbbeCursor *pCursr; /* The new table cursor */
BeFile *pFile; /* The underlying data file for this table */
int rc = SQLITE_OK; /* Return value */
int rw_mask; /* Permissions mask for opening a table */
int mode; /* Mode for opening a table */
*ppCursr = 0;
pCursr = sqliteMalloc( sizeof(*pCursr) );
if( pCursr==0 ) return SQLITE_NOMEM;
if( zTable ){
zFile = sqliteStrDup(zTable);
pFile = sqliteDbbeFindFile(zFile);
}else{
pFile = 0;
zFile = 0;
}
if( pFile==0 ){
pFile = sqliteMalloc( sizeof(*pFile) );
if( pFile==0 ){
sqliteFree(zFile);
return SQLITE_NOMEM;
}
if( zFile ){
if( !writeable || pBe->write ){
pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
}else{
pFile->dbf = 0;
}
}else{
int limit;
struct rc4 *pRc4;
char zRandom[50];
pRc4 = &pBe->rc4;
zFile = 0;
limit = 5;
while( 1 ){
randomName(&pBe->rc4, zRandom, "_temp_table_");
sqliteFree(zFile);
zFile = sqliteStrDup(zRandom);
if( sqliteDbbeFindFile(pBe, zFile)==0 ) break;
}
pFile->delOnClose = 1;
}
pFile->zName = zFile;
pFile->nRef = 1;
pFile->pPrev = 0;
if( pBe->pOpen ){
pBe->pOpen->pPrev = pFile;
}
pFile->pNext = pBe->pOpen;
pBe->pOpen = pFile;
}else{
sqliteFree(zFile);
pFile->nRef++;
}
pCursr->pBe = pBe;
pCursr->pFile = pFile;
pCursr->readPending = 0;
pCursr->needRewind = 1;
if( rc!=SQLITE_OK ){
sqliteDbbeCloseCursor(pCursr);
*ppCursr = 0;
}else{
*ppCursr = pCursr;
}
return rc;
}
/*
** Unlink a file from the database
*/
static void sqliteDbbeUnlinkFile(Dbbe *pBe, BeFile *pFile){
int h = sqliteStrHash(pFile->zName) %
(sizeof(pBe->aHash)/sizeof(pBe->aHash[0])));
if( pBe->aHash[h]==pFile ){
pBe->aHash[h] = pFile->pHash;
}else{
BeFile *pProbe;
for(pProbe=pBe->aHash[h]; pProbe; pProbe=pProbe->pHash){
if( pProbe->pHash==pFile ){
pProbe->pHash = pFile->pHash;
break;
}
}
}
}
/*
** Drop a table from the database. The file that corresponds
** to this table is deleted.
*/
void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
File *pFile;
pFile = sqliteDbbeFindFile(pBe, zTable);
if( pFile ){
sqliteDbbeUnlinkFile(pFile);
sqliteDbbeFreeFile(pFile);
}
}
/*
** Reorganize a table to reduce search times and disk usage.
*/
int sqliteDbbeReorganizeTable(Dbbe *pBe, const char *zTable){
return SQLITE_OK;
}
/*
** Close a cursor previously opened by sqliteDbbeOpenCursor().
**
** There can be multiple cursors pointing to the same open file.
** The underlying file is not closed until all cursors have been
** closed. This routine decrements the BeFile.nref field of the
** underlying file and closes the file when nref reaches 0.
*/
void sqliteDbbeCloseCursor(DbbeCursor *pCursr){
BeFile *pFile;
Dbbe *pBe;
if( pCursr==0 ) return;
pFile = pCursr->pFile;
pBe = pCursr->pBe;
pFile->nRef--;
if( pFile->nRef<=0 ){
if( pFile->pPrev ){
pFile->pPrev->pNext = pFile->pNext;
}else{
pBe->pOpen = pFile->pNext;
}
if( pFile->pNext ){
pFile->pNext->pPrev = pFile->pPrev;
}
if( pFile->delOnClose ){
sqliteDbbeUnlinkFile(pFile);
sqliteDbbeFreeFile(pFile);
}
}
memset(pCursr, 0, sizeof(*pCursr));
sqliteFree(pCursr);
}
/*
** Compute a hash on binary data
*/
static int sqliteBinaryHash(int n, char *z){
int h = 0;
while( n-- ){
h = (h<<9) ^ (h<<3) ^ h ^ *(z++);
}
if( h<0 ) h = -h;
return h;
}
/*
** Resize the hash table
*/
static void sqliteDbbeRehash(BeFile *pFile, int nHash){
int i, h;
datum *pRec, *pNextRec;
datum **aHash;
if( nHash<1 ) return;
aHash = sqliteMalloc( sizeof(aHash[0])*nHash );
if( aHash==0 ) return;
for(i=0; i<pFile->nHash; i++){
for(pRec=pFile->aHash[i]; pRec; pRec=pNextRec){
pNextRec = pRec->pHash;
h = sqliteBinaryHash(pRec->ksize, pRec->kptr) % nHash;
pRec->pHash = aHash[h];
aHash[h] = pRec;
}
}
sqliteFree(pFile->aHash);
pFile->aHash = aHash;
pFile->nHash = nHash;
}
/*
** Locate a datum in a file. Create it if it isn't already there and
** the createFlag is set.
*/
static datum **sqliteDbbeLookup(
BeFile *pFile, /* Where to look */
int nKey, /* The size of the key */
char *pKey, /* The key */
int *pH, /* Write the hash line here */
int createFlag /* Create a new entry if this is true */
){
int h;
datum **ppRec = 0;
datum *pNew;
if( pFile->nHash>0 ){
h = sqliteBinaryHash(nKey, pKey) % pFile->nHash;
ppRec = &pFile->aHash[h];
while( *ppRec ){
if( (**ppRec).ksize==nKey && memcpy((**ppRec).kptr, pKey, nKey)==0 ){
if( *pH ) *pH = h;
return ppRec;
}
}
}
if( createFlag==0 ) return 0;
if( (pFile->nRec + 1) > pFile->nHash*2 ){
int nHash = (pFile->nRec + 1)*4;
if( nHash<51 ) nHash = 51;
sqliteDbbeRehash(pFile, nHash);
if( pFile->nHash==0 ) return 0;
}
h = sqliteBinaryHash(nKey, pKey) % pFile->nHash;
pNew = sqliteMalloc( sizeof(*pNew) + nKey );
if( pNew==0 ) return 0;
pNew->kptr = (void*)&pNew[1];
pNew->ksize = nKey;
memcpy(pNew->kptr, pkey, nKey);
pNew->pHash = pFile->aHash[h];
pFile->aHash[h] = pNew;
pNew->dsize = 0;
pNew->dptr = 0;
pFile->nRec++;
if( pH ) *pH = h;
return &pFile->aHash[h];
}
/*
** Fetch a single record from an open cursor. Return 1 on success
** and 0 on failure.
*/
int sqliteDbbeFetch(DbbeCursor *pCursr, int nKey, char *pKey){
datum **ppRec;
ppRec = sqliteDbbeLookup(pCursr->pFile, nKey, pKey, &pCursr->h, 0);
if( ppRec ){
pCursr->pRec = *ppRec;
}
return pCursr->pRec!=0;
}
/*
** Return 1 if the given key is already in the table. Return 0
** if it is not.
*/
int sqliteDbbeTest(DbbeCursor *pCursr, int nKey, char *pKey){
return sqliteDbbeFetch(pCursr, nKey, pKey);
}
/*
** Copy bytes from the current key or data into a buffer supplied by
** the calling function. Return the number of bytes copied.
*/
int sqliteDbbeCopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
int n;
datum *pRec;
if( (pRec = pCursor->pRec)==0 || offset>=pRec->ksize ) return 0;
if( offset+size>pRec->ksize ){
n = pRec->ksize - offset;
}else{
n = size;
}
memcpy(zBuf, pRec->kptr[offset], n);
return n;
}
int sqliteDbbeCopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
int n;
datum *pRec;
if( (pRec = pCursr->pRec)==0 || offset>=pRec->dsize ) return 0;
if( offset+size>pRec->dsize ){
n = pRec->dsize - offset;
}else{
n = size;
}
memcpy(zBuf, &pRec->dptr[offset], n);
return n;
}
/*
** Return a pointer to bytes from the key or data. The data returned
** is ephemeral.
*/
char *sqliteDbbeReadKey(DbbeCursor *pCursr, int offset){
datum *pRec;
if( (pRec = pCursr->pRec)==0 || offset<0 || offset>=pRec->ksize ) return "";
return &pRec->kptr[offset];
}
char *sqliteDbbeReadData(DbbeCursor *pCursr, int offset){
datum *pRec;
if( (pRec = pCursr->pRec)==0 || offset<0 || offset>=pRec->dsize ) return "";
return &pRec->dptr[offset];
}
/*
** Return the total number of bytes in either data or key.
*/
int sqliteDbbeKeyLength(DbbeCursor *pCursr){
return pCursr->pRec ? pCursor->pRec->ksize : 0;
}
int sqliteDbbeDataLength(DbbeCursor *pCursr){
return pCursr->pRec ? pCursor->pRec->dsize : 0;
}
/*
** Make is so that the next call to sqliteNextKey() finds the first
** key of the table.
*/
int sqliteDbbeRewind(DbbeCursor *pCursr){
pCursr->needRewind = 1;
return SQLITE_OK;
}
/*
** Read the next key from the table. Return 1 on success. Return
** 0 if there are no more keys.
*/
int sqliteDbbeNextKey(DbbeCursor *pCursr){
int h;
BeFile *pFile;
if( pCursr==0 || (pFile = pCursr->pFile)==0 || pFile->nHash==0 ){
return 0;
}
if( pCursr->needRewind ){
pCursr->pRec = 0;
pCursr->h = -1;
}
if( pCursr->pRec ){
pCursr->pRec = pCursr->pRec->pHash;
}
if( pCursr->pRec==0 ){
for(h=pCursr->h; h<pFile->nHash && pFile->aHash[h]==0; h++){}
if( h>=pFile->nHash ){
pCursr->h = -1;
return 0;
}else{
pCursr->h = h;
pCursr->pRec = pFile->aHash[h];
return 1;
}
}
}
/*
** Get a new integer key.
*/
int sqliteDbbeNew(DbbeCursor *pCursr){
int iKey;
int go = 1;
int i;
struct rc4 *pRc4;
if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
pRc4 = &pCursr->pBe->rc4;
while( go ){
iKey = 0;
for(i=0; i<4; i++){
iKey = (iKey<<8) + rc4byte(pRc4);
}
if( iKey==0 ) continue;
go = sqliteDbbeLookup(pCursr->pFile, sizeof(iKey), &iKey, 0, 0)!=0;
}
return iKey;
}
/*
** Write an entry into the table. Overwrite any prior entry with the
** same key.
*/
int sqliteDbbePut(
DbbeCursor *pCursr, /* Write to this cursor */
int nKey, /* Size of the key */
char *pKey, /* The key */
int nData, /* Size of the data */
char *pData /* The data */
){
int rc;
datum **ppRec, *pRec;
if( pCursr->pFile==0 ) return SQLITE_ERROR;
ppRec = sqliteDbbeLookup(pCursr->pFile, nKey, pKey, &pCursr->h, 1);
if( ppRec==0 ) return SQLITE_NOMEM;
pRec = *ppRec;
sqliteFree(pRec->dptr);
pRec->dptr = sqliteMalloc( nData );
if( pRec->dptr==0 ) return SQLITE_NOMEM;
memcpy(pRec->dptr, pData, nData);
pRec->dsize = nData;
return SQLITE_OK;
}
/*
** Remove an entry from a table, if the entry exists.
*/
int sqliteDbbeDelete(DbbeCursor *pCursr, int nKey, char *pKey){
datum **ppRec, *pRec;
ppRec = sqliteDbbeLookcup(pCursr->pFile, nKey, pKey, 0, 0);
if( ppRec ){
pRec = *ppRec;
*ppRec = pRec->pNext;
if( pCursr->pRec==pRec ){
pCursr->pRec = 0;
pCursr->h = -1;
}
sqliteFree(pRec->dptr);
sqliteFree(pRec);
pCursr->pFile->nRec--;
}
return SQLITE_OK;
}
/*
** Open a temporary file. The file should be deleted when closed.
**
** Note that we can't use the old Unix trick of opening the file
** and then immediately unlinking the file. That works great
** under Unix, but fails when we try to port to Windows.
*/
int sqliteDbbeOpenTempFile(Dbbe *pBe, FILE **ppFile){
char *zFile; /* Full name of the temporary file */
char zBuf[50]; /* Base name of the temporary file */
int i; /* Loop counter */
int limit; /* Prevent an infinite loop */
int rc = SQLITE_OK; /* Value returned by this function */
for(i=0; i<pBe->nTemp; i++){
if( pBe->apTemp[i]==0 ) break;
}
if( i>=pBe->nTemp ){
pBe->nTemp++;
pBe->apTemp = sqliteRealloc(pBe->apTemp, pBe->nTemp*sizeof(FILE*) );
pBe->azTemp = sqliteRealloc(pBe->azTemp, pBe->nTemp*sizeof(char*) );
}
if( pBe->apTemp==0 ){
*ppFile = 0;
return SQLITE_NOMEM;
}
limit = 4;
zFile = 0;
do{
randomName(&pBe->rc4, zBuf, "/_temp_file_");
sqliteFree(zFile);
zFile = 0;
sqliteSetString(&zFile, pBe->zDir, zBuf, 0);
}while( access(zFile,0)==0 && limit-- >= 0 );
*ppFile = pBe->apTemp[i] = fopen(zFile, "w+");
if( pBe->apTemp[i]==0 ){
rc = SQLITE_ERROR;
sqliteFree(zFile);
pBe->azTemp[i] = 0;
}else{
pBe->azTemp[i] = zFile;
}
return rc;
}
/*
** Close a temporary file opened using sqliteDbbeOpenTempFile()
*/
void sqliteDbbeCloseTempFile(Dbbe *pBe, FILE *f){
int i;
for(i=0; i<pBe->nTemp; i++){
if( pBe->apTemp[i]==f ){
unlink(pBe->azTemp[i]);
sqliteFree(pBe->azTemp[i]);
pBe->apTemp[i] = 0;
pBe->azTemp[i] = 0;
break;
}
}
fclose(f);
}

View File

@ -26,7 +26,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.18 2000/08/22 13:40:51 drh Exp $
** $Id: main.c,v 1.19 2000/10/11 19:28:52 drh Exp $
*/
#include "sqliteInt.h"
@ -327,7 +327,6 @@ static int sqlite_default_busy_callback(
const char *NotUsed, /* The name of the table that is busy */
int count /* Number of times table has been busy */
){
int rc;
#if defined(HAVE_USLEEP) && HAVE_USLEEP
int delay = 10000;
int prior_delay = 0;

View File

@ -46,7 +46,9 @@
** + All functions are fully reentrant.
**
*/
#include <ctype.h>
#include "sqliteInt.h"
/*
** Undefine COMPATIBILITY to make some slight changes in the way things
** work. I think the changes are an improvement, but they are not

View File

@ -31,8 +31,8 @@ typedef struct TabResult {
static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
TabResult *p = (TabResult*)pArg;
int need;
int i, len;
char *z, *zVal;
int i;
char *z;
/* Make sure there is enough space in p->azResult to hold everything
** we need to remember from this invocation of the callback.

View File

@ -23,7 +23,7 @@
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.10 2000/09/30 22:46:07 drh Exp $
** $Id: tclsqlite.c,v 1.11 2000/10/11 19:28:52 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@ -138,7 +138,6 @@ static int DbBusyHandler(void *cd, const char *zTable, int nTries){
int rc;
char zVal[30];
char *zCmd;
char *zResult;
Tcl_DString cmd;
Tcl_DStringInit(&cmd);

View File

@ -26,15 +26,18 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.15 2000/09/14 01:21:10 drh Exp $
** $Id: util.c,v 1.16 2000/10/11 19:28:52 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>
/*
** If MEMORY_DEBUG is defined, then use versions of malloc() and
** free() that track memory usage and check for buffer overruns.
*/
#ifdef MEMORY_DEBUG
/*
** Allocate new memory and set it to zero. Return NULL if
** no memory is available.
@ -164,9 +167,14 @@ char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
}
return zNew;
}
#endif /* MEMORY_DEBUG */
/*
** The following versions of malloc() and free() are for use in a
** normal build.
*/
#if !defined(MEMORY_DEBUG)
#else /* !defined(MEMORY_DEBUG) */
/*
** Allocate new memory and set it to zero. Return NULL if
** no memory is available.
@ -219,7 +227,7 @@ char *sqliteStrNDup(const char *z, int n){
}
return zNew;
}
#endif /* MEMORY_DEBUG */
#endif /* !defined(MEMORY_DEBUG) */
/*
** Create a string from the 2nd and subsequent arguments (up to the

View File

@ -41,10 +41,11 @@
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.41 2000/09/14 01:21:10 drh Exp $
** $Id: vdbe.c,v 1.42 2000/10/11 19:28:53 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
#include <ctype.h>
/*
** SQL is translated into a sequence of instructions to be

View File

@ -27,7 +27,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.12 2000/08/28 15:51:45 drh Exp $
** $Id: vdbe.h,v 1.13 2000/10/11 19:28:53 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@ -196,6 +196,6 @@ int sqliteVdbeList(Vdbe*,sqlite_callback,void*,char**);
void sqliteVdbeResolveLabel(Vdbe*, int);
int sqliteVdbeCurrentAddr(Vdbe*);
void sqliteVdbeTrace(Vdbe*,FILE*);
void sqliteVdbeCompressSpace(Vdbe*,int);
#endif

View File

@ -17,6 +17,12 @@ proc chng {date desc} {
puts "<DD><P><UL>$desc</UL></P></DD>"
}
chng {2000 Oct 11 (Not Released)} {
<li>Added notes on how to compile for Windows95/98.</li>
<li>Add Doug Lea's memory allocator to the distribution, for completeness.</li>
<li>Removed a few variables that were not being used. Etc.</li>
}
chng {2000 Oct 8 (1.0.9)} {
<li>Added the <b>sqlite_..._printf()</b> interface routines.</li>
<li>Modified the <b>sqlite</b> shell program to use the new interface

View File

@ -1,7 +1,7 @@
#
# Run this Tcl script to generate the crosscompile.html file.
#
set rcsid {$Id: crosscompile.tcl,v 1.2 2000/07/31 19:16:32 drh Exp $}
set rcsid {$Id: crosscompile.tcl,v 1.3 2000/10/11 19:28:53 drh Exp $}
puts {<html>
<head>
@ -23,7 +23,9 @@ binaries. See the website for details.</p>
<p>This page describes how you can use MinGW configured as a
cross-compiler running under RedHat 6.0 Linux to generate a
binary for SQLite that runs under WinNT.</p>
binary for SQLite that runs under WinNT.
Some additional steps (described <a href="#win95">below</a>)
are needed to target Win95/98.</p>
}
proc Code {body} {
@ -123,6 +125,64 @@ make
</pre></blockquote>
</li>
</ol>
<a name="win95">
<h2>Targetting Windows95/98 instead of WindowsNT</h2>
<p>A small amount of additional work is needed to get SQLite running
under Windows95/98. The first problem is that the LockFile() and
UnlockFile() API that the Roth GDBM port uses does not work under
Windows95. The easiest workaround is to just disable file locking
in the GDBM library. You can do so by appending a few lines of code
to the end of one of the GDBM source files and compiling the library
using a special command-line option. Replace step (4) above as
follows:</p>
<ol>
<li value="4"><p>
Append text to the <b>systems.h</b> source file as follows:</p>
<blockquote><pre>
cat &gt;&gt;systems.h &lt;&lt;\END
#ifdef NO_LOCKS
#undef UNLOCK_FILE
#define UNLOCK_FILE(x)
#undef READLOCK_FILE
#define READLOCK_FILE(x)
#undef WRITELOCK_FILE
#define WRITELOCK_FILE(x)
#endif
END
</pre></blockquote>
<p>Then manually build the GDBM library with the extra
"NO_LOCKS" define as follows:</p>
<blockquote><pre>
i386-mingw32-gcc -DWIN32=1 -DNO_LOCKS -O2 -c *.c
i386-mingw32-ar cr libgdbm.a *.o
i386-mingw32-ranlib libgdbm.a
cd ..
</pre></blockquote>
</p></li>
</ol>
<p>Note that the locking problem has been reported and may actually
be fixed in the Roth GDBM distribution by the time you read this.
You should probably check before you make the above changes.</p>
<p>The above is all you have to do to get SQLite to work on Windows95.
But one more step is required to get it to work <i>well</i>. It
turns out that SQLite make heavy use of <b>malloc()</b> and
<b>free()</b> and the implementation of this functions
on Windows95 is particular poor. Large database queries will run
more than 10 times faster if you substitute a better memory allocator
such as the one by
<a href="http://g.oswego.edu/dl/html/malloc.html">Doug Lea</a>.
A copy of Doug's allocator is included in the <b>contrib</b>
directory of the source tree. Speed improvements are also reported
on WindowsNT when alternative memory allocators are used, though
the speedup is not as dramatic as it is with WIndows95.</p>
}
puts {
<p><hr /></p>