diff --git a/Makefile.in b/Makefile.in index f186f8ee84..b8d5f839c4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -48,8 +48,8 @@ LIBREADLINE = @TARGET_READLINE_LIBS@ # Object files for the SQLite library. # LIBOBJ = build.o dbbe.o dbbegdbm.o dbbemem.o delete.o expr.o insert.o \ - main.o parse.o printf.o select.o table.o tokenize.o update.o \ - util.o vdbe.o where.o tclsqlite.o + main.o parse.o printf.o random.o select.o table.o tokenize.o \ + update.o util.o vdbe.o where.o tclsqlite.o # All of the source code files. # @@ -66,6 +66,7 @@ SRC = \ $(TOP)/src/main.c \ $(TOP)/src/parse.y \ $(TOP)/src/printf.c \ + $(TOP)/src/random.c \ $(TOP)/src/select.c \ $(TOP)/src/shell.c \ $(TOP)/src/sqlite.h.in \ @@ -162,6 +163,9 @@ expr.o: $(TOP)/src/expr.c $(HDR) insert.o: $(TOP)/src/insert.c $(HDR) $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/insert.c +random.o: $(TOP)/src/random.c $(HDR) + $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/random.c + select.o: $(TOP)/src/select.c $(HDR) $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/select.c diff --git a/VERSION b/VERSION index f8f3c08725..9084fa2f71 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.18 +1.1.0 diff --git a/manifest b/manifest index b45d5c34c3..1a1d551049 100644 --- a/manifest +++ b/manifest @@ -1,34 +1,35 @@ -C Version\s1.0.18\s(CVS\s485) -D 2001-01-04T14:30:00 +C Changes\sto\sthe\sDBBE.\s\sMoving\stoward\shaving\smany\smore\nbackend\sdriver\schoices.\s(CVS\s176) +D 2001-01-13T14:34:06 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 -F Makefile.in 0b1fdafa55e1bf4d3a4f5213544130e66ef32052 +F Makefile.in 7efa81e2985b45ba73db27d55b70cc927f5abfd7 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 -F VERSION 049adaa0a3c5ffae5eb0267c11c84b9b206a550d +F VERSION 05e17b646a817240c206186f94f8f4c70974d5dc F configure 3dc1edb9dcf60215e31ff72b447935ab62211442 x F configure.in d892ca33db7e88a055519ce2f36dcb11020e8fff F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47 F src/build.c e2ceba852dc45ca899e68a042b29c3daab011575 -F src/dbbe.c 7e01384320075bf1d3e7fb54984df73435908809 -F src/dbbe.h d175a04b35ea75078274e059dcbcbf7c1262d42a -F src/dbbegdbm.c 4ac7222afff0cf91014803f8791740b6da825a2b -F src/dbbemem.c b55faed2e4719db47ade3483e85f7cb4b5fad39a +F src/dbbe.c 50e97d6dced263ce55ee992905a68dd65d15f9e8 +F src/dbbe.h c447dad03396ab7da690ba7b31dd37cb30cd64af +F src/dbbegdbm.c 9684095a11a2aad60322df0084d7e6cae3509ecc +F src/dbbemem.c f443a831e131eaf4e344ee96b3f52fec22cf04e0 F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065 F src/expr.c 7d7646afd52d1448237e5f517454cfb2d3d394d6 F src/insert.c f146f149ad2422a1dc3bfa7a1651a25940f98958 -F src/main.c 52355458131977c1ac40a006ce2fe2035f39069c +F src/main.c 340e5b04ce1222e4a75df7cb96bc2d0a236e881c F src/parse.y 25ee4d8efccc4b247c32fe4ab194e3dd8fd5a4ee F src/printf.c 1efb6b3e7f28a93be57132de3f8f400d2ac1460e +F src/random.c 3dc42fb35d834901577aa547308ff3c8941fea25 F src/select.c c1de8ac34131324fa05664b06b0ae1ee9c02905d F src/shell.c 441e20913cde0bb71281f4027623c623530241cd F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in fd86903777f1ee7bd0465243224a0fd2100eedc8 -F src/sqliteInt.h ed06214fc7054e43182ac351ebde913ede708639 +F src/sqliteInt.h c5d2cc9ab270c24d6f7d705b03c801135b50fb39 F src/table.c 5be76051a8ed6f6bfa641f4adc52529efa34fbf9 F src/tclsqlite.c 178adf318eab2ff480c288a87541d4ab1c37d985 F src/tokenize.c 6843f1d7a5d2ee08ceb10bdecfcc8684131ffcf7 F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc F src/util.c 0298100e6427a4b644f767ede12276fa7170fbb6 -F src/vdbe.c 3ddd7e3d17c954fc50afd5e73898371da09ad1c6 +F src/vdbe.c 46abf920b03a33e724c23049ab4017703ba18e28 F src/vdbe.h 140cdec3c56f70483e169f8ae657bd90f9fd6e98 F src/where.c 3dfad2ffd0aa994d5eceac88852f7189c8d1d3c8 F test/all.test 15cac2f6b2d4c55bf896212aff3cc9d6597b0490 @@ -76,7 +77,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad -P 81815a9c30ffc803cc03aad98936cba641674cd8 -R bf70551a041afaf128f504c8472d7ba7 +P 46b86abb1cc8e550acddba24e510d36eaf8ac6b9 +R 1d32d650ba38f8b6672c17c49e299816 U drh -Z 2ae1ca5ad1f48067a5d45adf3cf7ab78 +Z d3d2bca8c08f700ef95bd56e0b8b1082 diff --git a/manifest.uuid b/manifest.uuid index 62e0bdda71..201ff7ea33 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46b86abb1cc8e550acddba24e510d36eaf8ac6b9 \ No newline at end of file +c0730217a04323a1a73d125e3e7da32bcc8d58fc \ No newline at end of file diff --git a/src/dbbe.c b/src/dbbe.c index 43948c1e11..907aa73801 100644 --- a/src/dbbe.c +++ b/src/dbbe.c @@ -30,7 +30,7 @@ ** relatively simple to convert to a different database such ** as NDBM, SDBM, or BerkeleyDB. ** -** $Id: dbbe.c,v 1.21 2000/10/19 14:10:09 drh Exp $ +** $Id: dbbe.c,v 1.22 2001/01/13 14:34:06 drh Exp $ */ #include "sqliteInt.h" @@ -62,3 +62,90 @@ Dbbe *sqliteDbbeOpen( } return sqliteGdbmOpen(zName, writeFlag, createFlag, pzErrMsg); } + +/* +** 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 */ + char *zDir; /* Directory to hold the file */ + + for(i=0; inTemp; 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; + zDir = pBe->zDir; + if( zDir==0 ){ + zDir = "./"; + } + do{ + sqliteRandomName(zBuf, "/_temp_file_"); + sqliteFree(zFile); + zFile = 0; + sqliteSetString(&zFile, 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 sqliteGdbmOpenTempFile() +*/ +void sqliteDbbeCloseTempFile(Dbbe *pBe, FILE *f){ + int i; + for(i=0; inTemp; 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); +} + +/* +** Close all temporary files that happen to still be open. +** This routine is called when the database is being closed. +*/ +void sqliteDbbeCloseAllTempFiles(Dbbe *pBe){ + int i; + for(i=0; inTemp; 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); +} diff --git a/src/dbbe.h b/src/dbbe.h index 7c54a77b64..7d524cb037 100644 --- a/src/dbbe.h +++ b/src/dbbe.h @@ -28,7 +28,7 @@ ** This library was originally designed to support the following ** backends: GDBM, NDBM, SDBM, Berkeley DB. ** -** $Id: dbbe.h,v 1.8 2000/10/19 01:49:02 drh Exp $ +** $Id: dbbe.h,v 1.9 2001/01/13 14:34:06 drh Exp $ */ #ifndef _SQLITE_DBBE_H_ #define _SQLITE_DBBE_H_ @@ -53,7 +53,7 @@ */ typedef struct Dbbe Dbbe; typedef struct DbbeCursor DbbeCursor; - +typedef struct DbbeMethods DbbeMethods; /* ** Open a complete database. @@ -65,10 +65,13 @@ typedef struct DbbeCursor DbbeCursor; Dbbe *sqliteDbbeOpen(const char *zName, int write, int create, char **pzErr); /* -** This is the structure returned by sqliteDbbeOpen(). It contains pointers -** to all access routines for the database backend. +** Each of the various SQLite backends defines a set of methods for +** accessing the database. Pointers to the methods are contained in +** an instance of the following structure. A pointer to a static instance +** of this structure is assigned to the Dbbe structure that sqlileDbbeOpen +** returns. */ -struct Dbbe { +struct DbbeMethods { /* Close the whole database. */ void (*Close)(Dbbe*); @@ -149,4 +152,22 @@ struct Dbbe { void (*CloseTempFile)(Dbbe *, FILE *); }; +/* +** This is the structure returned by sqliteDbbeOpen(). It contains +** information common to all the different backend drivers. +** +** The information in this structure (with the exception the method +** pointers in the Dbbe.x field) is intended to be visible to +** the backend drivers only. Users should not access or modify +** this structure in any way other than the read the method pointers +** in Dbbe.x. +*/ +struct Dbbe { + struct DbbeMethods *x; /* Backend-specific methods for database access */ + char *zDir; /* The directory containing the database file(s) */ + int nTemp; /* Number of temporary files created */ + FILE **apTemp; /* Space to hold temporary file pointers */ + char **azTemp; /* Names of the temporary files */ +}; + #endif /* defined(_SQLITE_DBBE_H_) */ diff --git a/src/dbbegdbm.c b/src/dbbegdbm.c index 1e2702028f..6c2659a80b 100644 --- a/src/dbbegdbm.c +++ b/src/dbbegdbm.c @@ -30,7 +30,7 @@ ** relatively simple to convert to a different database such ** as NDBM, SDBM, or BerkeleyDB. ** -** $Id: dbbegdbm.c,v 1.1 2000/10/19 01:49:02 drh Exp $ +** $Id: dbbegdbm.c,v 1.2 2001/01/13 14:34:06 drh Exp $ */ #include "sqliteInt.h" #include @@ -57,20 +57,6 @@ struct BeFile { BeFile *pNext, *pPrev; /* Next and previous on list of open files */ }; -/* -** 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]; -}; - /* ** The following structure contains all information used by GDBM ** database driver. This is a subclass of the Dbbe structure. @@ -78,13 +64,8 @@ struct rc4 { typedef struct Dbbex Dbbex; struct Dbbex { Dbbe dbbe; /* The base class */ - char *zDir; /* The directory containing the database */ int write; /* True for write permission */ BeFile *pOpen; /* List of open files */ - 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 */ }; /* @@ -105,41 +86,12 @@ struct DbbeCursor { }; /* -** 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; -} - +struct DbbeList { + FILE *pOut; + Dbbe *pDbbe; +}; /* ** The "mkdir()" function only takes one argument under Windows. */ @@ -165,18 +117,7 @@ static void sqliteGdbmClose(Dbbe *pDbbe){ memset(pFile, 0, sizeof(*pFile)); sqliteFree(pFile); } - for(i=0; inTemp; 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); + sqliteDbbeCloseAllTempFiles(pDbbe); memset(pBe, 0, sizeof(*pBe)); sqliteFree(pBe); } @@ -190,9 +131,9 @@ static void sqliteGdbmClose(Dbbe *pDbbe){ static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){ char *zFile = 0; int i; - sqliteSetString(&zFile, pBe->zDir, "/", zTable, ".tbl", 0); + sqliteSetString(&zFile, pBe->dbbe.zDir, "/", zTable, ".tbl", 0); if( zFile==0 ) return 0; - for(i=strlen(pBe->zDir)+1; zFile[i]; i++){ + for(i=strlen(pBe->dbbe.zDir)+1; zFile[i]; i++){ int c = zFile[i]; if( isupper(c) ){ zFile[i] = tolower(c); @@ -203,27 +144,6 @@ static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){ return zFile; } -/* -** 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; -} - /* ** Open a new table cursor. Write a pointer to the corresponding ** DbbeCursor structure into *ppCursr. Return an integer success @@ -295,13 +215,11 @@ static int sqliteGdbmOpenCursor( } }else{ int limit; - struct rc4 *pRc4; char zRandom[50]; - pRc4 = &pBe->rc4; zFile = 0; limit = 5; do { - randomName(&pBe->rc4, zRandom, "_temp_table_"); + sqliteRandomName(zRandom, "_temp_table_"); sqliteFree(zFile); zFile = sqliteFileOfTable(pBe, zRandom); pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0); @@ -577,15 +495,10 @@ static int sqliteGdbmNew(DbbeCursor *pCursr){ datum key; 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); - } + iKey = sqliteRandomInteger(); if( iKey==0 ) continue; key.dptr = (char*)&iKey; key.dsize = 4; @@ -631,68 +544,31 @@ static int sqliteGdbmDelete(DbbeCursor *pCursr, int nKey, char *pKey){ } /* -** 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. +** This variable contains pointers to all of the access methods +** used to implement the GDBM backend. */ -static int sqliteGdbmOpenTempFile(Dbbe *pDbbe, 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 */ - Dbbex *pBe = (Dbbex*)pDbbe; - - for(i=0; inTemp; 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 sqliteGdbmOpenTempFile() -*/ -static void sqliteGdbmCloseTempFile(Dbbe *pDbbe, FILE *f){ - int i; - Dbbex *pBe = (Dbbex*)pDbbe; - for(i=0; inTemp; 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); -} +static struct DbbeMethods gdbmMethods = { + /* n Close */ sqliteGdbmClose, + /* OpenCursor */ sqliteGdbmOpenCursor, + /* DropTable */ sqliteGdbmDropTable, + /* ReorganizeTable */ sqliteGdbmReorganizeTable, + /* CloseCursor */ sqliteGdbmCloseCursor, + /* Fetch */ sqliteGdbmFetch, + /* Test */ sqliteGdbmTest, + /* CopyKey */ sqliteGdbmCopyKey, + /* CopyData */ sqliteGdbmCopyData, + /* ReadKey */ sqliteGdbmReadKey, + /* ReadData */ sqliteGdbmReadData, + /* KeyLength */ sqliteGdbmKeyLength, + /* DataLength */ sqliteGdbmDataLength, + /* NextKey */ sqliteGdbmNextKey, + /* Rewind */ sqliteGdbmRewind, + /* New */ sqliteGdbmNew, + /* Put */ sqliteGdbmPut, + /* Delete */ sqliteGdbmDelete, + /* OpenTempFile */ sqliteDbbeOpenTempFile, + /* CloseTempFile */ sqliteDbbeCloseTempFile +}; /* @@ -746,31 +622,10 @@ Dbbe *sqliteGdbmOpen( sqliteSetString(pzErrMsg, "out of memory", 0); return 0; } - pNew->dbbe.Close = sqliteGdbmClose; - pNew->dbbe.OpenCursor = sqliteGdbmOpenCursor; - pNew->dbbe.DropTable = sqliteGdbmDropTable; - pNew->dbbe.ReorganizeTable = sqliteGdbmReorganizeTable; - pNew->dbbe.CloseCursor = sqliteGdbmCloseCursor; - pNew->dbbe.Fetch = sqliteGdbmFetch; - pNew->dbbe.Test = sqliteGdbmTest; - pNew->dbbe.CopyKey = sqliteGdbmCopyKey; - pNew->dbbe.CopyData = sqliteGdbmCopyData; - pNew->dbbe.ReadKey = sqliteGdbmReadKey; - pNew->dbbe.ReadData = sqliteGdbmReadData; - pNew->dbbe.KeyLength = sqliteGdbmKeyLength; - pNew->dbbe.DataLength = sqliteGdbmDataLength; - pNew->dbbe.NextKey = sqliteGdbmNextKey; - pNew->dbbe.Rewind = sqliteGdbmRewind; - pNew->dbbe.New = sqliteGdbmNew; - pNew->dbbe.Put = sqliteGdbmPut; - pNew->dbbe.Delete = sqliteGdbmDelete; - pNew->dbbe.OpenTempFile = sqliteGdbmOpenTempFile; - pNew->dbbe.CloseTempFile = sqliteGdbmCloseTempFile; - pNew->zDir = (char*)&pNew[1]; - strcpy(pNew->zDir, zName); + pNew->dbbe.x = &gdbmMethods; + pNew->dbbe.zDir = (char*)&pNew[1]; + strcpy(pNew->dbbe.zDir, zName); pNew->write = writeFlag; pNew->pOpen = 0; - time(&statbuf.st_ctime); - rc4init(&pNew->rc4, (char*)&statbuf, sizeof(statbuf)); return &pNew->dbbe; } diff --git a/src/dbbemem.c b/src/dbbemem.c index c8118055eb..89b4aeed1e 100644 --- a/src/dbbemem.c +++ b/src/dbbemem.c @@ -28,7 +28,7 @@ ** ** This file uses an in-memory hash table as the database backend. ** -** $Id: dbbemem.c,v 1.5 2000/12/10 18:23:50 drh Exp $ +** $Id: dbbemem.c,v 1.6 2001/01/13 14:34:06 drh Exp $ */ #include "sqliteInt.h" #include @@ -342,20 +342,6 @@ struct MTable { Array data; /* The data in this stable */ }; -/* -** 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]; -}; - /* ** The following structure contains all information used by GDBM ** database driver. This is a subclass of the Dbbe structure. @@ -364,10 +350,6 @@ typedef struct Dbbex Dbbex; struct Dbbex { Dbbe dbbe; /* The base class */ Array tables; /* All tables of the database */ - 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 */ }; /* @@ -385,42 +367,6 @@ struct DbbeCursor { int needRewind; /* Next key should be the first */ }; -/* -** 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; -} - /* ** Forward declaration */ @@ -453,43 +399,11 @@ static void sqliteMemClose(Dbbe *pDbbe){ deleteMTable(pTble); } ArrayClear(&pBe->tables); - for(i=0; inTemp; 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); + sqliteDbbeCloseAllTempFiles(pDbbe); 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; -} - /* ** Translate the name of an SQL table (or index) into its ** canonical name. @@ -752,14 +666,9 @@ static int sqliteMemNew(DbbeCursor *pCursr){ Datum key; int go = 1; int i; - struct rc4 *pRc4; - pRc4 = &pCursr->pBe->rc4; while( go ){ - iKey = 0; - for(i=0; i<4; i++){ - iKey = (iKey<<8) + rc4byte(pRc4); - } + iKey = sqliteRandomInteger(); if( iKey==0 ) continue; key.p = (char*)&iKey; key.n = 4; @@ -804,69 +713,31 @@ static int sqliteMemDelete(DbbeCursor *pCursr, int nKey, char *pKey){ } /* -** 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. +** This variable contains pointers to all of the access methods +** used to implement the MEMORY backend. */ -static int sqliteMemOpenTempFile(Dbbe *pDbbe, FILE **ppTble){ - char *zName; /* 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 */ - Dbbex *pBe = (Dbbex*)pDbbe; - - for(i=0; inTemp; 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 ){ - *ppTble = 0; - return SQLITE_NOMEM; - } - limit = 4; - zName = 0; - do{ - randomName(&pBe->rc4, zBuf, "/tmp/_temp_file_"); - sqliteFree(zName); - zName = 0; - sqliteSetString(&zName, zBuf, 0); - }while( access(zName,0)==0 && limit-- >= 0 ); - *ppTble = pBe->apTemp[i] = fopen(zName, "w+"); - if( pBe->apTemp[i]==0 ){ - rc = SQLITE_ERROR; - sqliteFree(zName); - pBe->azTemp[i] = 0; - }else{ - pBe->azTemp[i] = zName; - } - return rc; -} - -/* -** Close a temporary file opened using sqliteMemOpenTempFile() -*/ -static void sqliteMemCloseTempFile(Dbbe *pDbbe, FILE *f){ - int i; - Dbbex *pBe = (Dbbex*)pDbbe; - for(i=0; inTemp; 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); -} - +static struct DbbeMethods memoryMethods = { + /* n Close */ sqliteMemClose, + /* OpenCursor */ sqliteMemOpenCursor, + /* DropTable */ sqliteMemDropTable, + /* ReorganizeTable */ sqliteMemReorganizeTable, + /* CloseCursor */ sqliteMemCloseCursor, + /* Fetch */ sqliteMemFetch, + /* Test */ sqliteMemTest, + /* CopyKey */ sqliteMemCopyKey, + /* CopyData */ sqliteMemCopyData, + /* ReadKey */ sqliteMemReadKey, + /* ReadData */ sqliteMemReadData, + /* KeyLength */ sqliteMemKeyLength, + /* DataLength */ sqliteMemDataLength, + /* NextKey */ sqliteMemNextKey, + /* Rewind */ sqliteMemRewind, + /* New */ sqliteMemNew, + /* Put */ sqliteMemPut, + /* Delete */ sqliteMemDelete, + /* OpenTempFile */ sqliteDbbeOpenTempFile, + /* CloseTempFile */ sqliteDbbeCloseTempFile +}; /* ** This routine opens a new database. For the GDBM driver @@ -884,7 +755,6 @@ Dbbe *sqliteMemOpen( char **pzErrMsg /* Write error messages (if any) here */ ){ Dbbex *pNew; - long now; pNew = sqliteMalloc( sizeof(*pNew) ); if( pNew==0 ){ @@ -892,27 +762,7 @@ Dbbe *sqliteMemOpen( return 0; } ArrayInit(&pNew->tables); - pNew->dbbe.Close = sqliteMemClose; - pNew->dbbe.OpenCursor = sqliteMemOpenCursor; - pNew->dbbe.DropTable = sqliteMemDropTable; - pNew->dbbe.ReorganizeTable = sqliteMemReorganizeTable; - pNew->dbbe.CloseCursor = sqliteMemCloseCursor; - pNew->dbbe.Fetch = sqliteMemFetch; - pNew->dbbe.Test = sqliteMemTest; - pNew->dbbe.CopyKey = sqliteMemCopyKey; - pNew->dbbe.CopyData = sqliteMemCopyData; - pNew->dbbe.ReadKey = sqliteMemReadKey; - pNew->dbbe.ReadData = sqliteMemReadData; - pNew->dbbe.KeyLength = sqliteMemKeyLength; - pNew->dbbe.DataLength = sqliteMemDataLength; - pNew->dbbe.NextKey = sqliteMemNextKey; - pNew->dbbe.Rewind = sqliteMemRewind; - pNew->dbbe.New = sqliteMemNew; - pNew->dbbe.Put = sqliteMemPut; - pNew->dbbe.Delete = sqliteMemDelete; - pNew->dbbe.OpenTempFile = sqliteMemOpenTempFile; - pNew->dbbe.CloseTempFile = sqliteMemCloseTempFile; - time(&now); - rc4init(&pNew->rc4, (char*)&now, sizeof(now)); + pNew->dbbe.x = &memoryMethods; + pNew->dbbe.zDir = 0; return &pNew->dbbe; } diff --git a/src/main.c b/src/main.c index 0a21177086..a707b67228 100644 --- a/src/main.c +++ b/src/main.c @@ -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.22 2000/12/10 18:23:50 drh Exp $ +** $Id: main.c,v 1.23 2001/01/13 14:34:06 drh Exp $ */ #include "sqliteInt.h" @@ -239,7 +239,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ */ void sqlite_close(sqlite *db){ int i; - db->pBe->Close(db->pBe); + db->pBe->x->Close(db->pBe); for(i=0; iapTblHash[i]; db->apTblHash[i] = 0; diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000000..726fefee4a --- /dev/null +++ b/src/random.c @@ -0,0 +1,127 @@ +/* +** Copyright (c) 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 a pseudo-random number +** generator (PRNG) for SQLite. +** +** Random numbers are used by some of the database backends in order +** to generate random integer keys for tables or random filenames. +** +** $Id: random.c,v 1.1 2001/01/13 14:34:07 drh Exp $ +*/ +#include "sqliteInt.h" + + +/* +** Get a single 8-bit random value from the RC4 PRNG. +*/ +int sqliteRandomByte(void){ + int t; + + /* + ** 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. + */ + static struct { + int isInit; + int i, j; + int s[256]; + } prng_state; + + /* Initialize the state of the random number generator once, + ** the first time this routine is called. The seed value does + ** not need to contain a lot of randomness since we are not + ** trying to do secure encryption or anything like that... + */ + if( !prng_state.isInit ){ + int i; + static char seed[] = " sqlite random seed"; + char k[256]; + time((time_t*)seed); + prng_state.j = 0; + prng_state.i = 0; + for(i=0; i<256; i++){ + prng_state.s[i] = i; + k[i] = seed[i%sizeof(seed)]; + } + for(i=0; i<256; i++){ + int t; + prng_state.j = (prng_state.j + prng_state.s[i] + k[i]) & 0xff; + t = prng_state.s[prng_state.j]; + prng_state.s[prng_state.j] = prng_state.s[i]; + prng_state.s[i] = t; + } + prng_state.isInit = 1; + } + + /* Generate and return single random byte + */ + prng_state.i = (prng_state.i + 1) & 0xff; + prng_state.j = (prng_state.j + prng_state.s[prng_state.i]) & 0xff; + t = prng_state.s[prng_state.i]; + prng_state.s[prng_state.i] = prng_state.s[prng_state.j]; + prng_state.s[prng_state.j] = t; + t = prng_state.s[prng_state.i] + prng_state.s[prng_state.j]; + return t & 0xff; +} + +/* +** Return a random 32-bit integer. The integer is generated by making +** 4 calls to sqliteRandomByte(). +*/ +int sqliteRandomInteger(void){ + int r; + int i; + r = sqliteRandomByte(); + for(i=1; i<4; i++){ + r = (r<<8) + sqliteRandomByte(); + } + return r; +} + + +/* +** 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. +*/ +void sqliteRandomName(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 = sqliteRandomByte() % (sizeof(zRandomChars) - 1); + zBuf[j++] = zRandomChars[c]; + } + zBuf[j] = 0; +} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5b777ef518..b6e6021020 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,7 +23,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.33 2000/12/10 18:23:51 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.34 2001/01/13 14:34:07 drh Exp $ */ #include "sqlite.h" #include "dbbe.h" @@ -419,3 +419,8 @@ void sqliteExprResolveInSelect(Parse*, Expr*); int sqliteExprAnalyzeAggregates(Parse*, Expr*); void sqliteParseInfoReset(Parse*); Vdbe *sqliteGetVdbe(Parse*); +int sqliteRandomByte(void); +int sqliteRandomInteger(void); +void sqliteRandomName(char*,char*); +int sqliteDbbeOpenTempFile(Dbbe*, FILE**); +void sqliteDbbeCloseTempFile(Dbbe*, FILE*); diff --git a/src/vdbe.c b/src/vdbe.c index bfdb65b79b..749f1e039c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -41,7 +41,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.49 2000/12/10 18:35:20 drh Exp $ +** $Id: vdbe.c,v 1.50 2001/01/13 14:34:07 drh Exp $ */ #include "sqliteInt.h" #include @@ -696,7 +696,7 @@ static void Cleanup(Vdbe *p){ p->azColName = 0; for(i=0; inCursor; i++){ if( p->aCsr[i].pCursor ){ - p->pBe->CloseCursor(p->aCsr[i].pCursor); + p->pBe->x->CloseCursor(p->aCsr[i].pCursor); p->aCsr[i].pCursor = 0; } } @@ -713,7 +713,7 @@ static void Cleanup(Vdbe *p){ p->nMem = 0; for(i=0; inList; i++){ if( p->apList[i] ){ - p->pBe->CloseTempFile(p->pBe, p->apList[i]); + p->pBe->x->CloseTempFile(p->pBe, p->apList[i]); p->apList[i] = 0; } } @@ -953,6 +953,7 @@ int sqliteVdbeExec( Op *pOp; /* Current operation */ int rc; /* Value to return */ Dbbe *pBe = p->pBe; /* The backend driver */ + DbbeMethods *pBex = pBe->x; /* The backend driver methods */ sqlite *db = p->db; /* The database */ char **zStack; Stack *aStack; @@ -1809,10 +1810,10 @@ int sqliteVdbeExec( for(j=p->nCursor; j<=i; j++) p->aCsr[j].pCursor = 0; p->nCursor = i+1; }else if( p->aCsr[i].pCursor ){ - pBe->CloseCursor(p->aCsr[i].pCursor); + pBex->CloseCursor(p->aCsr[i].pCursor); } do { - rc = pBe->OpenCursor(pBe,pOp->p3,pOp->p2,&p->aCsr[i].pCursor); + rc = pBex->OpenCursor(pBe,pOp->p3,pOp->p2,&p->aCsr[i].pCursor); switch( rc ){ case SQLITE_BUSY: { if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){ @@ -1853,7 +1854,7 @@ int sqliteVdbeExec( case OP_Close: { int i = pOp->p1; if( i>=0 && inCursor && p->aCsr[i].pCursor ){ - pBe->CloseCursor(p->aCsr[i].pCursor); + pBex->CloseCursor(p->aCsr[i].pCursor); p->aCsr[i].pCursor = 0; } break; @@ -1871,11 +1872,11 @@ int sqliteVdbeExec( VERIFY( if( tos<0 ) goto not_enough_stack; ) if( i>=0 && inCursor && p->aCsr[i].pCursor ){ if( aStack[tos].flags & STK_Int ){ - pBe->Fetch(p->aCsr[i].pCursor, sizeof(int), + pBex->Fetch(p->aCsr[i].pCursor, sizeof(int), (char*)&aStack[tos].i); }else{ if( Stringify(p, tos) ) goto no_mem; - pBe->Fetch(p->aCsr[i].pCursor, aStack[tos].n, + pBex->Fetch(p->aCsr[i].pCursor, aStack[tos].n, zStack[tos]); } p->nFetch++; @@ -1937,11 +1938,11 @@ int sqliteVdbeExec( VERIFY( if( tos<0 ) goto not_enough_stack; ) if( VERIFY( i>=0 && inCursor && ) p->aCsr[i].pCursor ){ if( aStack[tos].flags & STK_Int ){ - alreadyExists = pBe->Test(p->aCsr[i].pCursor, sizeof(int), + alreadyExists = pBex->Test(p->aCsr[i].pCursor, sizeof(int), (char*)&aStack[tos].i); }else{ if( Stringify(p, tos) ) goto no_mem; - alreadyExists = pBe->Test(p->aCsr[i].pCursor,aStack[tos].n, + alreadyExists = pBex->Test(p->aCsr[i].pCursor,aStack[tos].n, zStack[tos]); } } @@ -1967,7 +1968,7 @@ int sqliteVdbeExec( if( VERIFY( i<0 || i>=p->nCursor || ) p->aCsr[i].pCursor==0 ){ v = 0; }else{ - v = pBe->New(p->aCsr[i].pCursor); + v = pBex->New(p->aCsr[i].pCursor); } VERIFY( NeedStack(p, p->tos+1); ) p->tos++; @@ -2000,7 +2001,7 @@ int sqliteVdbeExec( nKey = sizeof(int); zKey = (char*)&aStack[nos].i; } - pBe->Put(p->aCsr[i].pCursor, nKey, zKey, + pBex->Put(p->aCsr[i].pCursor, nKey, zKey, aStack[tos].n, zStack[tos]); } POPSTACK; @@ -2028,7 +2029,7 @@ int sqliteVdbeExec( nKey = aStack[tos].n; zKey = zStack[tos]; } - pBe->Delete(p->aCsr[i].pCursor, nKey, zKey); + pBex->Delete(p->aCsr[i].pCursor, nKey, zKey); } POPSTACK; break; @@ -2082,29 +2083,29 @@ int sqliteVdbeExec( VERIFY( if( NeedStack(p, tos) ) goto no_mem; ) if( VERIFY( i>=0 && inCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){ if( p->aCsr[i].keyAsData ){ - amt = pBe->KeyLength(pCrsr); + amt = pBex->KeyLength(pCrsr); if( amt<=sizeof(int)*(p2+1) ){ aStack[tos].flags = STK_Null; break; } - pAddr = (int*)pBe->ReadKey(pCrsr, sizeof(int)*p2); + pAddr = (int*)pBex->ReadKey(pCrsr, sizeof(int)*p2); if( *pAddr==0 ){ aStack[tos].flags = STK_Null; break; } - z = pBe->ReadKey(pCrsr, *pAddr); + z = pBex->ReadKey(pCrsr, *pAddr); }else{ - amt = pBe->DataLength(pCrsr); + amt = pBex->DataLength(pCrsr); if( amt<=sizeof(int)*(p2+1) ){ aStack[tos].flags = STK_Null; break; } - pAddr = (int*)pBe->ReadData(pCrsr, sizeof(int)*p2); + pAddr = (int*)pBex->ReadData(pCrsr, sizeof(int)*p2); if( *pAddr==0 ){ aStack[tos].flags = STK_Null; break; } - z = pBe->ReadData(pCrsr, *pAddr); + z = pBex->ReadData(pCrsr, *pAddr); } zStack[tos] = z; aStack[tos].n = strlen(z) + 1; @@ -2127,11 +2128,11 @@ int sqliteVdbeExec( VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; ) if( VERIFY( i>=0 && inCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){ - char *z = pBe->ReadKey(pCrsr, 0); + char *z = pBex->ReadKey(pCrsr, 0); if( p->aCsr[i].keyAsData ){ zStack[tos] = z; aStack[tos].flags = STK_Str; - aStack[tos].n = pBe->KeyLength(pCrsr); + aStack[tos].n = pBex->KeyLength(pCrsr); }else{ memcpy(&aStack[tos].i, z, sizeof(int)); aStack[tos].flags = STK_Int; @@ -2148,7 +2149,7 @@ int sqliteVdbeExec( case OP_Rewind: { int i = pOp->p1; if( VERIFY( i>=0 && inCursor && ) p->aCsr[i].pCursor!=0 ){ - pBe->Rewind(p->aCsr[i].pCursor); + pBex->Rewind(p->aCsr[i].pCursor); } break; } @@ -2161,7 +2162,7 @@ int sqliteVdbeExec( case OP_Next: { int i = pOp->p1; if( VERIFY( i>=0 && inCursor && ) p->aCsr[i].pCursor!=0 ){ - if( pBe->NextKey(p->aCsr[i].pCursor)==0 ){ + if( pBex->NextKey(p->aCsr[i].pCursor)==0 ){ pc = pOp->p2 - 1; }else{ p->nFetch++; @@ -2211,8 +2212,8 @@ int sqliteVdbeExec( int *aIdx; int nIdx; int j, k; - nIdx = pBe->DataLength(pCrsr)/sizeof(int); - aIdx = (int*)pBe->ReadData(pCrsr, 0); + nIdx = pBex->DataLength(pCrsr)/sizeof(int); + aIdx = (int*)pBex->ReadData(pCrsr, 0); if( nIdx>1 ){ k = *(aIdx++); if( k>nIdx-1 ) k = nIdx-1; @@ -2257,10 +2258,10 @@ int sqliteVdbeExec( Integerify(p, nos); newVal = aStack[nos].i; if( Stringify(p, tos) ) goto no_mem; - r = pBe->Fetch(pCrsr, aStack[tos].n, zStack[tos]); + r = pBex->Fetch(pCrsr, aStack[tos].n, zStack[tos]); if( r==0 ){ /* Create a new record for this index */ - pBe->Put(pCrsr, aStack[tos].n, zStack[tos], + pBex->Put(pCrsr, aStack[tos].n, zStack[tos], sizeof(int), (char*)&newVal); }else{ /* Extend the existing record */ @@ -2268,32 +2269,32 @@ int sqliteVdbeExec( int *aIdx; int k; - nIdx = pBe->DataLength(pCrsr)/sizeof(int); + nIdx = pBex->DataLength(pCrsr)/sizeof(int); if( nIdx==1 ){ aIdx = sqliteMalloc( sizeof(int)*4 ); if( aIdx==0 ) goto no_mem; aIdx[0] = 2; - pBe->CopyData(pCrsr, 0, sizeof(int), (char*)&aIdx[1]); + pBex->CopyData(pCrsr, 0, sizeof(int), (char*)&aIdx[1]); aIdx[2] = newVal; - pBe->Put(pCrsr, aStack[tos].n, zStack[tos], + pBex->Put(pCrsr, aStack[tos].n, zStack[tos], sizeof(int)*4, (char*)aIdx); sqliteFree(aIdx); }else{ - aIdx = (int*)pBe->ReadData(pCrsr, 0); + aIdx = (int*)pBex->ReadData(pCrsr, 0); k = aIdx[0]; if( kPut(pCrsr, aStack[tos].n, zStack[tos], + pBex->Put(pCrsr, aStack[tos].n, zStack[tos], sizeof(int)*nIdx, (char*)aIdx); }else{ nIdx *= 2; aIdx = sqliteMalloc( sizeof(int)*nIdx ); if( aIdx==0 ) goto no_mem; - pBe->CopyData(pCrsr, 0, sizeof(int)*(k+1), (char*)aIdx); + pBex->CopyData(pCrsr, 0, sizeof(int)*(k+1), (char*)aIdx); aIdx[k+1] = newVal; aIdx[0]++; - pBe->Put(pCrsr, aStack[tos].n, zStack[tos], + pBex->Put(pCrsr, aStack[tos].n, zStack[tos], sizeof(int)*nIdx, (char*)aIdx); sqliteFree(aIdx); } @@ -2333,12 +2334,12 @@ int sqliteVdbeExec( Integerify(p, nos); oldVal = aStack[nos].i; if( Stringify(p, tos) ) goto no_mem; - r = pBe->Fetch(pCrsr, aStack[tos].n, zStack[tos]); + r = pBex->Fetch(pCrsr, aStack[tos].n, zStack[tos]); if( r==0 ) break; - nIdx = pBe->DataLength(pCrsr)/sizeof(int); - aIdx = (int*)pBe->ReadData(pCrsr, 0); + nIdx = pBex->DataLength(pCrsr)/sizeof(int); + aIdx = (int*)pBex->ReadData(pCrsr, 0); if( (nIdx==1 && aIdx[0]==oldVal) || (aIdx[0]==1 && aIdx[1]==oldVal) ){ - pBe->Delete(pCrsr, aStack[tos].n, zStack[tos]); + pBex->Delete(pCrsr, aStack[tos].n, zStack[tos]); }else{ k = aIdx[0]; for(j=1; j<=k && aIdx[j]!=oldVal; j++){} @@ -2349,7 +2350,7 @@ int sqliteVdbeExec( if( aIdx[0]*3 + 1 < nIdx ){ nIdx /= 2; } - pBe->Put(pCrsr, aStack[tos].n, zStack[tos], + pBex->Put(pCrsr, aStack[tos].n, zStack[tos], sizeof(int)*nIdx, (char*)aIdx); } } @@ -2365,7 +2366,7 @@ int sqliteVdbeExec( ** from the disk. */ case OP_Destroy: { - pBe->DropTable(pBe, pOp->p3); + pBex->DropTable(pBe, pOp->p3); break; } @@ -2374,7 +2375,7 @@ int sqliteVdbeExec( ** Compress, optimize, and tidy up the GDBM file named by P3. */ case OP_Reorganize: { - pBe->ReorganizeTable(pBe, pOp->p3); + pBex->ReorganizeTable(pBe, pOp->p3); break; } @@ -2396,9 +2397,9 @@ int sqliteVdbeExec( for(j=p->nList; j<=i; j++) p->apList[j] = 0; p->nList = i+1; }else if( p->apList[i] ){ - pBe->CloseTempFile(pBe, p->apList[i]); + pBex->CloseTempFile(pBe, p->apList[i]); } - rc = pBe->OpenTempFile(pBe, &p->apList[i]); + rc = pBex->OpenTempFile(pBe, &p->apList[i]); if( rc!=SQLITE_OK ){ sqliteSetString(pzErrMsg, "unable to open a temporary file", 0); } @@ -2468,7 +2469,7 @@ int sqliteVdbeExec( int i = pOp->p1; VERIFY( if( i<0 ) goto bad_instruction; ) if( VERIFY( inList && ) p->apList[i]!=0 ){ - pBe->CloseTempFile(pBe, p->apList[i]); + pBex->CloseTempFile(pBe, p->apList[i]); p->apList[i] = 0; } break;