diff --git a/Makefile.in b/Makefile.in index fa845cc949..f3af9281f1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,8 +47,8 @@ LIBREADLINE = @TARGET_READLINE_LIBS@ # Object files for the SQLite library. # -LIBOBJ = btree.o build.o dbbe.o dbbegdbm.o dbbemem.o delete.o expr.o insert.o \ - main.o pager.o parse.o printf.o random.o select.o table.o \ +LIBOBJ = build.o dbbe.o dbbegdbm.o dbbemem.o delete.o expr.o insert.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. @@ -83,8 +83,6 @@ SRC = \ # TESTSRC = \ $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ $(TOP)/src/md5.c # This is the default Makefile target. The objects listed here @@ -118,15 +116,10 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c HDR = \ sqlite.h \ $(TOP)/src/sqliteInt.h \ - $(TOP)/src/btree.h \ $(TOP)/src/dbbe.h \ - $(TOP)/src/pager.h \ $(TOP)/src/vdbe.h \ parse.h -btree.o: $(TOP)/src/btree.c $(HDR) - $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/btree.c - build.o: $(TOP)/src/build.c $(HDR) $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/build.c @@ -195,9 +188,6 @@ tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) printf.o: $(TOP)/src/printf.c $(HDR) $(TCC) $(GDBM_FLAGS) $(TCL_FLAGS) -c $(TOP)/src/printf.c -pager.o: $(TOP)/src/pager.c $(HDR) - $(TCC) $(GDBM_FLAGS) $(TCL_FLAGS) -c $(TOP)/src/pager.c - gdbmdump: $(TOP)/tool/gdbmdump.c $(TCC) $(GDBM_FLAGS) -o gdbmdump $(TOP)/tool/gdbmdump.c $(LIBGDBM) @@ -207,8 +197,8 @@ tclsqlite: $(TOP)/src/tclsqlite.c libsqlite.a testfixture: $(TOP)/src/tclsqlite.c libsqlite.a $(TESTSRC) $(TCC) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture \ - $(TESTSRC) $(TOP)/src/tclsqlite.c $(TOP)/src/btree.c \ - $(TOP)/src/pager.c libsqlite.a $(LIBGDBM) $(LIBTCL) + $(TESTSRC) $(TOP)/src/tclsqlite.c \ + libsqlite.a $(LIBGDBM) $(LIBTCL) test: testfixture sqlite ./testfixture $(TOP)/test/all.test diff --git a/VERSION b/VERSION index 94956151c6..15245f3a2a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.31 +1.0.32 diff --git a/manifest b/manifest index dc6753567c..dc432fcb4b 100644 --- a/manifest +++ b/manifest @@ -1,16 +1,17 @@ -C BTree\sand\spager\sare\sworking\spretty\swell\snow.\s(CVS\s234) -D 2001-07-02T17:51:46 +C Add\sability\sto\squote\stable\sand\scolumn\snames\sin\sexpression.\s(CVS\s235) +D 2001-07-23T14:33:03 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 -F Makefile.in df14e0f23d6946304d4681c24799d1ece965bf74 +F Makefile.in a4595a83d56549b527dace5415729d20995f717b F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 -F VERSION 71874cb7e2a53c2bd22bb6affa7d223dd94a7a13 +F VERSION 00453ed53ff28fe8e701e1609e81f1b9df12adab F configure d2051345f49f7e48604423da26e086a745c86a47 x F configure.in e7465c88bbfb76882f97769c2dd90dbba8eca5db F doc/lemon.html 3ddeef6e5dee69a2bb6f5d8e4975b58f2fd8e11c F doc/report1.txt 734cbae63b1310cc643fe5e9e3da1ab55a79b99e F notes/notes1.txt b7c0812b704a022e88c621146ae50955c923d464 F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e -F notes/notes3.txt 985bf688b59f1f52bfe6e4b1f896efdeffac1432 +F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3 +F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16 F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4 F src/btree.c d6bbe3152ce3eb47ffd0c797897bf75c5ca784fc F src/btree.h 5fb5799bcb39900386ce6cae61fa33e357851ffe @@ -28,7 +29,7 @@ F src/ex/dbbemird.c b00aef85656fa0a101dac2c32e12922ad106715a F src/ex/pg.c 2bbf6a94f37226d06337868b6bf4d7affc60197f F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7 -F src/expr.c c4c24c3af1eba094a816522eb0e085bed518ee16 +F src/expr.c f64760004afc10c1c1232ae7ece2947452aa70dd F src/insert.c aa528e20a787af85432a61daaea6df394bd251d7 F src/main.c 0a13c7a2beb8ce36aee43daf8c95989b200727a7 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c @@ -43,10 +44,8 @@ F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 3e5906f72608f0fd4394dfbb1d7e8d35b8353677 F src/sqliteInt.h 47845c60e2e196b5409d774936a56700b1611f00 F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6 -F src/tclsqlite.c 7acb8887c44622214edb0dedeaab2593a3f86c62 +F src/tclsqlite.c 386f502060325d9cb05d418bf0f1cf6a4b57c873 F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4 -F src/test2.c 0183625225a860397b4fd3041aefb48f77e4630a -F src/test3.c e13021bfd3bbbe6ec6c26d1de15d1a86ba5aae44 F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf F src/update.c 0cf789656a936d4356668393267692fa4b03ffc6 F src/util.c 1b396ac34e30dd6222d82e996c17b161bbc906bc @@ -54,8 +53,6 @@ F src/vdbe.c f93be4414ba892df9c5589815d2a57c1fb12c820 F src/vdbe.h dc1205da434c6a9da03b5d6b089270bbc8e6d437 F src/where.c 0c542fc44bd85152dfb8507862cfe2e60c629e9f F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048 -F test/btree.test 084f03bfc05551baff13b5e6ba61713d31e5621d -F test/btree2.test 485210a30a8efaf629bdc5d923918bbce6fae658 F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf @@ -68,8 +65,8 @@ F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6 F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a F test/main.test da635f9e078cd21ddf074e727381a715064489ff F test/malloc.test 3daa97f6a9577d8f4c6e468b274333af19ce5861 -F test/pager.test aa902a867ce6b925214d28e17400001946e0e5a4 F test/printf.test 4c71871e1a75a2dacb673945fc13ddb30168798f +F test/quote.test 40a3164af8456933a81312803fa8cdb21b205c12 F test/rowid.test 128453599def7435e988216f7fe89c7450b8a9a3 F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f F test/select2.test 04ac3bd69298f58c7d0883159bab42ab9ad6021c @@ -99,7 +96,7 @@ F www/arch.fig 4f246003b7da23bd63b8b0af0618afb4ee3055c8 F www/arch.png 8dae0766d42ed3de9ed013c1341a5792bcf633e6 F www/arch.tcl a40380c1fe0080c43e6cc5c20ed70731511b06be F www/c_interface.tcl ddca19005c47dd5a15882addc02fff5de83d8ed9 -F www/changes.tcl 822b425cc50cb8e21563dd1aa0e4b79cf780f3dc +F www/changes.tcl a805374f79bba9a77fd88516163681dab323b5d0 F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9 @@ -110,7 +107,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad -P 55c89bfdd35f1ad494618a451f9a1ed08502ae07 -R 3d46d052f2a18aacc3a120e98e99a6ad +P a84fb078baf96dbfb5983981127dfc905074b7f9 +R eec7e6db07d9a5655c1c80f7d8ed8318 U drh -Z 32466dc4499f5824fce13920537543bc +Z 7c7623637c745880923fb1ff59c11d78 diff --git a/manifest.uuid b/manifest.uuid index d394676b55..fd3919c35f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a84fb078baf96dbfb5983981127dfc905074b7f9 \ No newline at end of file +029e3a3a5dd8d4923af50bb2c9f31b1b7cd9439e \ No newline at end of file diff --git a/notes/notes2b.txt b/notes/notes2b.txt new file mode 100644 index 0000000000..e9d2274449 --- /dev/null +++ b/notes/notes2b.txt @@ -0,0 +1,26 @@ + + +add_to_page(cursor, payload, child){ + if( fits-on-current-page ){ + insert (child,payload) into cursor + return + } + if( cursor is root page ){ + split cursor+(child,payload) into page1, center, page2 + set cursor page to page1,center,page2 + return + } + if( move_some_data_left || move_some_data_right ){ + add (child,payload) to cursor + return + } + split cursor+(child,payload) into self, center, page2 + move_up(cursor) + add_to_page(cursor, center, page2) +} + + +split(in_page, payload, child_pgno, out_page1, center_payload, out_page2){ + // It might be that in_page==out_page1 + +} diff --git a/notes/notes3.txt b/notes/notes3.txt index 9d6d5938e4..19d07768d4 100644 --- a/notes/notes3.txt +++ b/notes/notes3.txt @@ -1,65 +1,125 @@ The Proposed New SQLite 2.0 Interface design. (April 16, 2001) Primary access routines: - - sqlite *sqlite_open(const char *zFilename, int mode); - int sqlite_compile(sqlite*, const char *zSql); - int sqlite_row(sqlite*, int *argc, const char ***argv); - int sqlite_finish(sqlite*); - int sqlite_close(sqlite*); + Control functions: + sqlite *sqlite_open(const char *zFilename); + int sqlite_compile(sqlite*, const char *zSql); + int sqlite_next(sqlite*); + int sqlite_abort(sqlite*); + int sqlite_finish(sqlite*); + sqlite *sqlite_dup(sqlite*); + int sqlite_close(sqlite*); + Access functions: + int sqlite_status(sqlite*); + char *sqlite_error_text(sqlite*); + int sqlite_column_count(sqlite*); + char **sqlite_column_names(sqlite*); + char **sqlite_values(sqlite*); + const char sqlite_version[]; + const char sqlite_encoding[]; Secondary access routines: + Control functions: + int sqlite_complete(const char *); + char *sqlite_mprintf(const char *zFormat, ...) + char *sqlite_vmprintf(const char *zFormat, va_list ap); + int sqlite_compile_printf(sqlite*, const char *zFormat, ...); + int sqlite_compile_vprintf(sqlite*, const char *zFormat, va_list ap); + int sqlite_eval(sqlite*, const char *zSql); + int sqlite_retry(sqlite*); + int sqlite_eval_printf(sqlite*, const char *zFormat, ...); + int sqlite_eval_vprintf(sqlite*, const char *zFormat, va_list ap); + int sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*); + int sqlite_busy_timeout(sqlite*, int ms); + Access functions: + int sqlite_row_count(sqlite*); + char ***sqlite_rows(sqlite*, int iRow); - const char sqlite_version[]; - const char sqlite_encoding[]; - int sqlite_complete(const char *); - sqlite *sqlite_dup(sqlite*); - int sqlite_abort(sqlite*); - void sqlite_interrupt(sqlite*); - char *sqlite_errmsg(sqlite*); - const char **sqlite_columns(sqlite*); - int sqlite_argc(sqlite*); - const char **sqlite_argv(sqlite*); - char *sqlite_vmprintf(const char *zFormat, va_list); - int sqlite_table(sqlite*, int *nrow, int *ncolumn, const char ***argv); - void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*); +Usage examples: + Getting an entire result table in one go: + sqlite *p = sqlite_open("ex.db"); + sqlite_eval(p, "SELECT * FROM table_one"); + for(i=0; i0 ) printf("\n"); + for(j=0; j0 ) printf("\n"); + for(j=0; j0 ) printf("\n"); + for(j=0; j0 ) printf("\n"); + for(j=0; jiTable = -1; for(i=0; inId; i++){ int j; diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a663f46ff3..95ae3c5c8b 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -23,7 +23,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.20 2001/07/01 22:12:02 drh Exp $ +** $Id: tclsqlite.c,v 1.21 2001/07/23 14:33:04 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -510,12 +510,8 @@ int TCLSH_MAIN(int argc, char **argv){ #ifdef SQLITE_TEST { extern int Sqlitetest1_Init(Tcl_Interp*); - extern int Sqlitetest2_Init(Tcl_Interp*); - extern int Sqlitetest3_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); Sqlitetest1_Init(interp); - Sqlitetest2_Init(interp); - Sqlitetest3_Init(interp); Md5_Init(interp); } #endif diff --git a/src/test2.c b/src/test2.c deleted file mode 100644 index 92ac2f5d68..0000000000 --- a/src/test2.c +++ /dev/null @@ -1,416 +0,0 @@ -/* -** Copyright (c) 2001 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/ -** -************************************************************************* -** Code for testing the pager.c module in SQLite. This code -** is not included in the SQLite library. It is used for automated -** testing of the SQLite library. -** -** $Id: test2.c,v 1.2 2001/04/28 16:52:42 drh Exp $ -*/ -#include "sqliteInt.h" -#include "pager.h" -#include "tcl.h" -#include -#include - -/* -** Interpret an SQLite error number -*/ -static char *errorName(int rc){ - char *zName; - switch( rc ){ - case SQLITE_OK: zName = "SQLITE_OK"; break; - case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; - case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; - case SQLITE_PERM: zName = "SQLITE_PERM"; break; - case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; - case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; - case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; - case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; - case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; - case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; - case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; - case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; - case SQLITE_FULL: zName = "SQLITE_FULL"; break; - case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; - case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; - default: zName = "SQLITE_Unknown"; break; - } - return zName; -} - -/* -** Usage: pager_open FILENAME N-PAGE -** -** Open a new pager -*/ -static int pager_open( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - int nPage; - int rc; - char zBuf[100]; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " FILENAME N-PAGE\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; - rc = sqlitepager_open(&pPager, argv[1], nPage, 0); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - sprintf(zBuf,"0x%x",(int)pPager); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: pager_close ID -** -** Close the given pager. -*/ -static int pager_close( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - rc = sqlitepager_close(pPager); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: pager_rollback ID -** -** Rollback changes -*/ -static int pager_rollback( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - rc = sqlitepager_rollback(pPager); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: pager_commit ID -** -** Commit all changes -*/ -static int pager_commit( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - rc = sqlitepager_commit(pPager); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: pager_stats ID -** -** Return pager statistics. -*/ -static int pager_stats( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - int i, *a; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - a = sqlitepager_stats(pPager); - for(i=0; i<9; i++){ - static char *zName[] = { - "ref", "page", "max", "size", "state", "err", - "hit", "miss", "ovfl", - }; - char zBuf[100]; - Tcl_AppendElement(interp, zName[i]); - sprintf(zBuf,"%d",a[i]); - Tcl_AppendElement(interp, zBuf); - } - return TCL_OK; -} - -/* -** Usage: pager_pagecount ID -** -** Return the size of the database file. -*/ -static int pager_pagecount( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - char zBuf[100]; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - sprintf(zBuf,"%d",sqlitepager_pagecount(pPager)); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: page_get ID PGNO -** -** Return a pointer to a page from the database. -*/ -static int page_get( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - char zBuf[100]; - void *pPage; - int pgno; - int rc; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID PGNO\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; - rc = sqlitepager_get(pPager, pgno, &pPage); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - sprintf(zBuf,"0x%x",(int)pPage); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: page_lookup ID PGNO -** -** Return a pointer to a page if the page is already in cache. -** If not in cache, return an empty string. -*/ -static int page_lookup( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Pager *pPager; - char zBuf[100]; - void *pPage; - int pgno; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID PGNO\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPager) ) return TCL_ERROR; - if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; - pPage = sqlitepager_lookup(pPager, pgno); - if( pPage ){ - sprintf(zBuf,"0x%x",(int)pPage); - Tcl_AppendResult(interp, zBuf, 0); - } - return TCL_OK; -} - -/* -** Usage: page_unref PAGE -** -** Drop a pointer to a page. -*/ -static int page_unref( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - void *pPage; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " PAGE\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR; - rc = sqlitepager_unref(pPage); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: page_read PAGE -** -** Return the content of a page -*/ -static int page_read( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - char zBuf[100]; - void *pPage; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " PAGE\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR; - memcpy(zBuf, pPage, sizeof(zBuf)); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: page_number PAGE -** -** Return the page number for a page. -*/ -static int page_number( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - char zBuf[100]; - void *pPage; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " PAGE\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR; - sprintf(zBuf, "%d", sqlitepager_pagenumber(pPage)); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: page_write PAGE DATA -** -** Write something into a page. -*/ -static int page_write( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - void *pPage; - int rc; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " PAGE DATA\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR; - rc = sqlitepager_write(pPage); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - strncpy((char*)pPage, argv[2], SQLITE_PAGE_SIZE-1); - ((char*)pPage)[SQLITE_PAGE_SIZE-1] = 0; - return TCL_OK; -} - -/* -** Register commands with the TCL interpreter. -*/ -int Sqlitetest2_Init(Tcl_Interp *interp){ - Tcl_CreateCommand(interp, "pager_open", pager_open, 0, 0); - Tcl_CreateCommand(interp, "pager_close", pager_close, 0, 0); - Tcl_CreateCommand(interp, "pager_commit", pager_commit, 0, 0); - Tcl_CreateCommand(interp, "pager_rollback", pager_rollback, 0, 0); - Tcl_CreateCommand(interp, "pager_stats", pager_stats, 0, 0); - Tcl_CreateCommand(interp, "pager_pagecount", pager_pagecount, 0, 0); - Tcl_CreateCommand(interp, "page_get", page_get, 0, 0); - Tcl_CreateCommand(interp, "page_lookup", page_lookup, 0, 0); - Tcl_CreateCommand(interp, "page_unref", page_unref, 0, 0); - Tcl_CreateCommand(interp, "page_read", page_read, 0, 0); - Tcl_CreateCommand(interp, "page_write", page_write, 0, 0); - Tcl_CreateCommand(interp, "page_number", page_number, 0, 0); - return TCL_OK; -} diff --git a/src/test3.c b/src/test3.c deleted file mode 100644 index 27745079a8..0000000000 --- a/src/test3.c +++ /dev/null @@ -1,844 +0,0 @@ -/* -** Copyright (c) 2001 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/ -** -************************************************************************* -** Code for testing the btree.c module in SQLite. This code -** is not included in the SQLite library. It is used for automated -** testing of the SQLite library. -** -** $Id: test3.c,v 1.7 2001/07/02 17:51:46 drh Exp $ -*/ -#include "sqliteInt.h" -#include "pager.h" -#include "btree.h" -#include "tcl.h" -#include -#include - -/* -** Interpret an SQLite error number -*/ -static char *errorName(int rc){ - char *zName; - switch( rc ){ - case SQLITE_OK: zName = "SQLITE_OK"; break; - case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; - case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; - case SQLITE_PERM: zName = "SQLITE_PERM"; break; - case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; - case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; - case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; - case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; - case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; - case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; - case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; - case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; - case SQLITE_FULL: zName = "SQLITE_FULL"; break; - case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; - case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; - default: zName = "SQLITE_Unknown"; break; - } - return zName; -} - -/* -** Usage: btree_open FILENAME -** -** Open a new database -*/ -static int btree_open( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - char zBuf[100]; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " FILENAME\"", 0); - return TCL_ERROR; - } - rc = sqliteBtreeOpen(argv[1], 0666, 10, &pBt); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - sprintf(zBuf,"0x%x",(int)pBt); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: btree_close ID -** -** Close the given database. -*/ -static int btree_close( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeClose(pBt); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_begin_transaction ID -** -** Start a new transaction -*/ -static int btree_begin_transaction( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeBeginTrans(pBt); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_rollback ID -** -** Rollback changes -*/ -static int btree_rollback( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeRollback(pBt); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_commit ID -** -** Commit all changes -*/ -static int btree_commit( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeCommit(pBt); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_create_table ID -** -** Create a new table in the database -*/ -static int btree_create_table( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc, iTable; - char zBuf[30]; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeCreateTable(pBt, &iTable); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - sprintf(zBuf, "%d", iTable); - Tcl_AppendResult(interp, zBuf, 0); - return TCL_OK; -} - -/* -** Usage: btree_drop_table ID TABLENUM -** -** Delete an entire table from the database -*/ -static int btree_drop_table( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int iTable; - int rc; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID TABLENUM\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; - rc = sqliteBtreeDropTable(pBt, iTable); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_clear_table ID TABLENUM -** -** Remove all entries from the given table but keep the table around. -*/ -static int btree_clear_table( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int iTable; - int rc; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID TABLENUM\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; - rc = sqliteBtreeClearTable(pBt, iTable); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** Usage: btree_get_meta ID -** -** Return meta data -*/ -static int btree_get_meta( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - Btree *pBt; - int rc; - int i; - int aMeta[SQLITE_N_BTREE_META]; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ID\"", 0); - return TCL_ERROR; - } - if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; - rc = sqliteBtreeGetMeta(pBt, aMeta); - if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, errorName(rc), 0); - return TCL_ERROR; - } - for(i=0; i0} -} {1} -do_test btree-3.8 { - btree_key $::c1 -} {five} -do_test btree-3.9 { - btree_data $::c1 -} {5.00} -do_test btree-3.10 { - btree_next $::c1 - btree_key $::c1 -} {four} -do_test btree-3.11 { - btree_data $::c1 -} {4.00} -do_test btree-3.12 { - btree_next $::c1 - btree_key $::c1 -} {one} -do_test btree-3.13 { - btree_data $::c1 -} {1.00} -do_test btree-3.14 { - btree_next $::c1 - btree_key $::c1 -} {six} -do_test btree-3.15 { - btree_data $::c1 -} {6.00} -do_test btree-3.16 { - btree_next $::c1 - btree_key $::c1 -} {three} -do_test btree-3.17 { - btree_data $::c1 -} {3.00} -do_test btree-3.18 { - btree_next $::c1 - btree_key $::c1 -} {two} -do_test btree-3.19 { - btree_data $::c1 -} {2.00} -do_test btree-3.20 { - btree_next $::c1 - btree_key $::c1 -} {} -do_test btree-3.21 { - btree_data $::c1 -} {} - -# Commit the changes, reopen and reread the data -# -do_test btree-3.22 { - set rc [catch {btree_close_cursor $::c1} msg] - lappend rc $msg -} {0 {}} -do_test btree-3.22.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-3.23 { - set rc [catch {btree_commit $::b1} msg] - lappend rc $msg -} {0 {}} -do_test btree-3.23.1 { - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-3.24 { - file size test1.bt -} {2048} -do_test btree-3.25 { - set rc [catch {btree_cursor $::b1 2} ::c1] - if {$rc} {lappend rc $::c1} - set rc -} {0} -do_test btree-3.25.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-3.26 { - set rc [btree_move_to $::c1 {}] - expr {$rc>0} -} {1} -do_test btree-3.27 { - btree_key $::c1 -} {five} -do_test btree-3.28 { - btree_data $::c1 -} {5.00} -do_test btree-3.29 { - btree_next $::c1 - btree_key $::c1 -} {four} -do_test btree-3.30 { - btree_data $::c1 -} {4.00} -do_test btree-3.31 { - btree_next $::c1 - btree_key $::c1 -} {one} -do_test btree-3.32 { - btree_data $::c1 -} {1.00} -do_test btree-3.33 { - btree_next $::c1 - btree_key $::c1 -} {six} -do_test btree-3.34 { - btree_data $::c1 -} {6.00} -do_test btree-3.35 { - btree_next $::c1 - btree_key $::c1 -} {three} -do_test btree-3.36 { - btree_data $::c1 -} {3.00} -do_test btree-3.37 { - btree_next $::c1 - btree_key $::c1 -} {two} -do_test btree-3.38 { - btree_data $::c1 -} {2.00} -do_test btree-3.39 { - btree_next $::c1 - btree_key $::c1 -} {} -do_test btree-3.40 { - btree_data $::c1 -} {} -do_test btree-3.41 { - lindex [btree_pager_stats $::b1] 1 -} {2} - - -# Now try a delete -# -do_test btree-4.1 { - btree_begin_transaction $::b1 - btree_move_to $::c1 one - btree_key $::c1 -} {one} -do_test btree-4.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-4.2 { - btree_delete $::c1 -} {} -do_test btree-4.3 { - btree_key $::c1 -} {six} -do_test btree-4.4 { - btree_next $::c1 - btree_key $::c1 -} {six} -do_test btree-4.5 { - btree_next $::c1 - btree_key $::c1 -} {three} -do_test btree-4.4 { - btree_move_to $::c1 {} - set r {} - while 1 { - set key [btree_key $::c1] - if {$key==""} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00} - -# Commit and make sure the delete is still there. -# -do_test btree-4.5 { - btree_commit $::b1 - btree_move_to $::c1 {} - set r {} - while 1 { - set key [btree_key $::c1] - if {$key==""} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00} - -# Completely close the database and reopen it. Then check -# the data again. -# -do_test btree-4.6 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-4.7 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-4.8 { - btree_close $::b1 - set ::b1 [btree_open test1.bt] - set ::c1 [btree_cursor $::b1 2] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-4.9 { - set r {} - while 1 { - set key [btree_key $::c1] - if {$key==""} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00} - -# Try to read and write meta data -# -do_test btree-5.1 { - btree_get_meta $::b1 -} {0 0 0 0} -do_test btree-5.2 { - set rc [catch {btree_update_meta $::b1 1 2 3 4} msg] - lappend rc $msg -} {1 SQLITE_ERROR} -do_test btree-5.3 { - btree_begin_transaction $::b1 - set rc [catch {btree_update_meta $::b1 1 2 3 4} msg] - lappend rc $msg -} {0 {}} -do_test btree-5.4 { - btree_get_meta $::b1 -} {0 2 3 4} -do_test btree-5.5 { - btree_close_cursor $::c1 - btree_rollback $::b1 - btree_get_meta $::b1 -} {0 0 0 0} -do_test btree-5.6 { - btree_begin_transaction $::b1 - btree_update_meta $::b1 999 10 20 30 - btree_commit $::b1 - btree_get_meta $::b1 -} {0 10 20 30} - -proc select_all {cursor} { - set r {} - btree_move_to $cursor {} - while 1 { - set key [btree_key $cursor] - if {$key==""} break - lappend r $key - lappend r [btree_data $cursor] - btree_next $cursor - } - return $r -} -proc select_keys {cursor} { - set r {} - btree_move_to $cursor {} - while 1 { - set key [btree_key $cursor] - if {$key==""} break - lappend r $key - btree_next $cursor - } - return $r -} - -# Try to create a new table in the database file -# -do_test btree-6.1 { - set rc [catch {btree_create_table $::b1} msg] - lappend rc $msg -} {1 SQLITE_ERROR} -do_test btree-6.2 { - btree_begin_transaction $::b1 - set ::t2 [btree_create_table $::b1] -} {3} -do_test btree-6.2.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-6.2.2 { - set ::c2 [btree_cursor $::b1 $::t2] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-6.2.3 { - btree_insert $::c2 ten 10 - btree_key $::c2 -} {ten} -do_test btree-6.3 { - btree_commit $::b1 - set ::c1 [btree_cursor $::b1 2] - lindex [btree_pager_stats $::b1] 1 -} {3} -do_test btree-6.3.1 { - select_all $::c1 -} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00} -#btree_page_dump $::b1 3 -do_test btree-6.4 { - select_all $::c2 -} {ten 10} - -# Drop the new table, then create it again anew. -# -do_test btree-6.5 { - btree_begin_transaction $::b1 -} {} -do_test btree-6.6 { - btree_close_cursor $::c2 -} {} -do_test btree-6.6.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-6.7 { - btree_drop_table $::b1 $::t2 -} {} -do_test btree-6.7.1 { - lindex [btree_get_meta $::b1] 0 -} {1} -do_test btree-6.8 { - set ::t2 [btree_create_table $::b1] -} {3} -do_test btree-6.8.1 { - lindex [btree_get_meta $::b1] 0 -} {0} -do_test btree-6.9 { - set ::c2 [btree_cursor $::b1 $::t2] - lindex [btree_pager_stats $::b1] 1 -} {3} - -do_test btree-6.9.1 { - btree_move_to $::c2 {} - btree_key $::c2 -} {} - -# If we drop table 2 it just clears the table. Table 2 always exists. -# -do_test btree-6.10 { - btree_close_cursor $::c1 - btree_drop_table $::b1 2 - set ::c1 [btree_cursor $::b1 2] - btree_move_to $::c1 {} - btree_key $::c1 -} {} -do_test btree-6.11 { - btree_commit $::b1 - select_all $::c1 -} {} -do_test btree-6.12 { - select_all $::c2 -} {} -do_test btree-6.13 { - btree_close_cursor $::c2 - lindex [btree_pager_stats $::b1] 1 -} {2} - -# Check to see that pages defragment properly. To do this test we will -# -# 1. Fill the first page table 2 with data. -# 2. Delete every other entry of table 2. -# 3. Insert a single entry that requires more contiguous -# space than is available. -# -do_test btree-7.1 { - btree_begin_transaction $::b1 -} {} -catch {unset key} -catch {unset data} -do_test btree-7.2 { - for {set i 0} {$i<36} {incr i} { - set key [format %03d $i] - set data "*** $key ***" - btree_insert $::c1 $key $data - } - lrange [btree_cursor_dump $::c1] 4 5 -} {8 1} -do_test btree-7.3 { - btree_move_to $::c1 000 - while {[btree_key $::c1]!=""} { - btree_delete $::c1 - btree_next $::c1 - btree_next $::c1 - } - lrange [btree_cursor_dump $::c1] 4 5 -} {512 19} -#btree_page_dump $::b1 2 -do_test btree-7.4 { - btree_insert $::c1 018 {*** 018 ***+++} - btree_key $::c1 -} {018} -do_test btree-7.5 { - lrange [btree_cursor_dump $::c1] 4 5 -} {480 1} -#btree_page_dump $::b1 2 - -# Delete an entry to make a hole of a known size, then immediately recreate -# that entry. This tests the path into allocateSpace where the hole exactly -# matches the size of the desired space. -# -do_test btree-7.6 { - btree_move_to $::c1 007 - btree_delete $::c1 - btree_move_to $::c1 011 - btree_delete $::c1 -} {} -do_test btree-7.7 { - lindex [btree_cursor_dump $::c1] 5 -} {3} -#btree_page_dump $::b1 2 -do_test btree-7.8 { - btree_insert $::c1 007 {*** 007 ***} - lindex [btree_cursor_dump $::c1] 5 -} {2} -#btree_page_dump $::b1 2 - -# Make sure the freeSpace() routine properly coaleses adjacent memory blocks -# -do_test btree-7.9 { - btree_move_to $::c1 013 - btree_delete $::c1 - lrange [btree_cursor_dump $::c1] 4 5 -} {536 2} -do_test btree-7.10 { - btree_move_to $::c1 009 - btree_delete $::c1 - lrange [btree_cursor_dump $::c1] 4 5 -} {564 2} -do_test btree-7.11 { - btree_move_to $::c1 018 - btree_delete $::c1 - lrange [btree_cursor_dump $::c1] 4 5 -} {596 2} -do_test btree-7.13 { - btree_move_to $::c1 033 - btree_delete $::c1 - lrange [btree_cursor_dump $::c1] 4 5 -} {624 3} -do_test btree-7.14 { - btree_move_to $::c1 035 - btree_delete $::c1 - lrange [btree_cursor_dump $::c1] 4 5 -} {652 2} -#btree_page_dump $::b1 2 -do_test btree-7.15 { - lindex [btree_pager_stats $::b1] 1 -} {2} - -# Check to see that data on overflow pages work correctly. -# -do_test btree-8.1 { - set data "*** This is a very long key " - while {[string length $data]<256} {append data $data} - set ::data $data - btree_insert $::c1 020 $data -} {} -#btree_page_dump $::b1 2 -do_test btree-8.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -#btree_pager_ref_dump $::b1 -do_test btree-8.2 { - string length [btree_data $::c1] -} [string length $::data] -do_test btree-8.3 { - btree_data $::c1 -} $::data -do_test btree-8.4 { - btree_delete $::c1 -} {} -do_test btree-8.4.1 { - lindex [btree_get_meta $::b1] 0 -} [expr {int(([string length $::data]-238+1019)/1020)}] -do_test btree-8.5 { - set data "*** This is an even longer key" - while {[string length $data]<2000} {append data $data} - set ::data $data - btree_insert $::c1 020 $data -} {} -do_test btree-8.6 { - string length [btree_data $::c1] -} [string length $::data] -do_test btree-8.7 { - btree_data $::c1 -} $::data -do_test btree-8.8 { - btree_commit $::b1 - btree_data $::c1 -} $::data -do_test btree-8.9 { - btree_close_cursor $::c1 - btree_close $::b1 - set ::b1 [btree_open test1.bt] - set ::c1 [btree_cursor $::b1 2] - btree_move_to $::c1 020 - btree_data $::c1 -} $::data -do_test btree-8.10 { - btree_begin_transaction $::b1 - btree_delete $::c1 -} {} -do_test btree-8.11 { - lindex [btree_get_meta $::b1] 0 -} [expr {int(([string length $::data]-238+1019)/1020)}] - -# Now check out keys on overflow pages. -# -do_test btree-8.12 { - set ::keyprefix "This is a long prefix to a key " - while {[string length $::keyprefix]<256} {append ::keyprefix $::keyprefix} - btree_close_cursor $::c1 - btree_drop_table $::b1 2 - lindex [btree_get_meta $::b1] 0 -} {4} -do_test btree-8.12.1 { - set ::c1 [btree_cursor $::b1 2] - btree_insert $::c1 ${::keyprefix}1 1 - btree_data $::c1 -} {1} -do_test btree-8.13 { - btree_key $::c1 -} ${keyprefix}1 -do_test btree-8.14 { - btree_insert $::c1 ${::keyprefix}2 2 - btree_insert $::c1 ${::keyprefix}3 3 - btree_key $::c1 -} ${keyprefix}3 -do_test btree-8.15 { - btree_move_to $::c1 ${::keyprefix}2 - btree_data $::c1 -} {2} -do_test btree-8.16 { - btree_move_to $::c1 ${::keyprefix}1 - btree_data $::c1 -} {1} -do_test btree-8.17 { - btree_move_to $::c1 ${::keyprefix}3 - btree_data $::c1 -} {3} -do_test btree-8.18 { - lindex [btree_get_meta $::b1] 0 -} {1} -do_test btree-8.19 { - btree_move_to $::c1 ${::keyprefix}2 - btree_key $::c1 -} ${::keyprefix}2 -#btree_page_dump $::b1 2 -do_test btree-8.20 { - btree_delete $::c1 - btree_next $::c1 - btree_key $::c1 -} ${::keyprefix}3 -#btree_page_dump $::b1 2 -do_test btree-8.21 { - lindex [btree_get_meta $::b1] 0 -} {2} -do_test btree-8.22 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-8.23 { - btree_close_cursor $::c1 - btree_drop_table $::b1 2 - set ::c1 [btree_cursor $::b1 2] - lindex [btree_get_meta $::b1] 0 -} {4} -do_test btree-8.24 { - lindex [btree_pager_stats $::b1] 1 -} {2} -#btree_pager_ref_dump $::b1 - -# Check page splitting logic -# -do_test btree-9.1 { - for {set i 1} {$i<=19} {incr i} { - set key [format %03d $i] - set data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - } -} {} -#btree_tree_dump $::b1 2 -#btree_pager_ref_dump $::b1 -#set pager_refinfo_enable 1 -do_test btree-9.2 { - btree_insert $::c1 020 {*** 020 *** 020 *** 020 *** 020 ***} - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020} -#btree_page_dump $::b1 5 -#btree_page_dump $::b1 2 -#btree_page_dump $::b1 7 -#btree_pager_ref_dump $::b1 -#set pager_refinfo_enable 0 - -# The previous "select_keys" command left the cursor pointing at the root -# page. So there should only be two pages checked out. 2 (the root) and -# page 1. -do_test btree-9.2.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -for {set i 1} {$i<=20} {incr i} { - do_test btree-9.3.$i.1 [subst { - btree_move_to $::c1 [format %03d $i] - btree_key $::c1 - }] [format %03d $i] - do_test btree-9.3.$i.2 [subst { - btree_move_to $::c1 [format %03d $i] - string range \[btree_data $::c1\] 0 10 - }] "*** [format %03d $i] ***" -} -do_test btree-9.4.1 { - lindex [btree_pager_stats $::b1] 1 -} {3} - -# Check the page joining logic. -# -#btree_page_dump $::b1 2 -#btree_pager_ref_dump $::b1 -do_test btree-9.4.2 { - btree_move_to $::c1 005 - btree_delete $::c1 -} {} -#btree_page_dump $::b1 2 -for {set i 1} {$i<=19} {incr i} { - if {$i==5} continue - do_test btree-9.5.$i.1 [subst { - btree_move_to $::c1 [format %03d $i] - btree_key $::c1 - }] [format %03d $i] - do_test btree-9.5.$i.2 [subst { - btree_move_to $::c1 [format %03d $i] - string range \[btree_data $::c1\] 0 10 - }] "*** [format %03d $i] ***" -} -#btree_pager_ref_dump $::b1 -do_test btree-9.6 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-9.7 { - btree_rollback $::b1 - lindex [btree_pager_stats $::b1] 1 -} {0} - -# Create a tree of depth two. That is, there is a single divider entry -# on the root pages and two leaf pages. Then delete the divider entry -# see what happens. -# -do_test btree-10.1 { - btree_begin_transaction $::b1 - btree_drop_table $::b1 2 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-10.2 { - set ::c1 [btree_cursor $::b1 2] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-10.3 { - for {set i 1} {$i<=20} {incr i} { - set key [format %03d $i] - set data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - } - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020} -#btree_page_dump $::b1 7 -#btree_page_dump $::b1 2 -#btree_page_dump $::b1 6 -do_test btree-10.4 { - btree_move_to $::c1 011 - btree_delete $::c1 - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 012 013 014 015 016 017 018 019 020} -#btree_tree_dump $::b1 2 -#btree_pager_ref_dump $::b1 -for {set i 1} {$i<=20} {incr i} { - do_test btree-10.5.$i { - btree_move_to $::c1 [format %03d $i] - lindex [btree_pager_stats $::b1] 1 - } {2} - #btree_pager_ref_dump $::b1 - #btree_tree_dump $::b1 2 -} - -# Create a tree with lots more pages -# -catch {unset ::data} -catch {unset ::key} -for {set i 21} {$i<=1000} {incr i} { - do_test btree-11.1.$i.1 { - set key [format %03d $i] - set ::data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - btree_key $::c1 - } [format %03d $i] - do_test btree-11.1.$i.2 { - btree_data $::c1 - } $::data - set ::key [format %03d [expr {$i/2}]] - if {$::key=="011"} {set ::key 010} - do_test btree-11.1.$i.3 { - btree_move_to $::c1 $::key - btree_key $::c1 - } $::key -} -catch {unset ::data} -catch {unset ::key} - -# Make sure our reference count is still correct. -# -do_test btree-11.2 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-11.3 { - set ::c1 [btree_cursor $::b1 2] - lindex [btree_pager_stats $::b1] 1 -} {2} -#btree_page_dump $::b1 2 - -# Delete the dividers on the root page -# -do_test btree-11.4 { - btree_move_to $::c1 257 - btree_delete $::c1 - btree_next $::c1 - btree_key $::c1 -} {258} -do_test btree-11.4.1 { - btree_move_to $::c1 256 - btree_key $::c1 -} {256} -do_test btree-11.4.2 { - btree_move_to $::c1 258 - btree_key $::c1 -} {258} -do_test btree-11.4.3 { - btree_move_to $::c1 259 - btree_key $::c1 -} {259} -do_test btree-11.4.4 { - btree_move_to $::c1 257 - set n [btree_key $::c1] - expr {$n==256||$n==258} -} {1} -do_test btree-11.5 { - btree_move_to $::c1 513 - btree_delete $::c1 - btree_next $::c1 - btree_key $::c1 -} {514} -do_test btree-11.5.1 { - btree_move_to $::c1 512 - btree_key $::c1 -} {512} -do_test btree-11.5.2 { - btree_move_to $::c1 514 - btree_key $::c1 -} {514} -do_test btree-11.5.3 { - btree_move_to $::c1 515 - btree_key $::c1 -} {515} -do_test btree-11.5.4 { - btree_move_to $::c1 513 - set n [btree_key $::c1] - expr {$n==512||$n==514} -} {1} -do_test btree-11.6 { - btree_move_to $::c1 769 - btree_delete $::c1 - btree_next $::c1 - btree_key $::c1 -} {770} -do_test btree-11.6.1 { - btree_move_to $::c1 768 - btree_key $::c1 -} {768} -do_test btree-11.6.2 { - btree_move_to $::c1 771 - btree_key $::c1 -} {771} -do_test btree-11.6.3 { - btree_move_to $::c1 770 - btree_key $::c1 -} {770} -do_test btree-11.6.4 { - btree_move_to $::c1 769 - set n [btree_key $::c1] - expr {$n==768||$n==770} -} {1} -#btree_page_dump $::b1 2 -#btree_page_dump $::b1 25 - -# Change the data on an intermediate node such that the node becomes overfull -# and has to split. We happen to know that intermediate nodes exist on -# 337, 401 and 465 by the btree_page_dumps above -# -catch {unset ::data} -set ::data {This is going to be a very long data segment} -append ::data $::data -append ::data $::data -do_test btree-12.1 { - btree_insert $::c1 337 $::data - btree_data $::c1 -} $::data -do_test btree-12.2 { - btree_insert $::c1 401 $::data - btree_data $::c1 -} $::data -do_test btree-12.3 { - btree_insert $::c1 465 $::data - btree_data $::c1 -} $::data -do_test btree-12.4 { - btree_move_to $::c1 337 - btree_key $::c1 -} {337} -do_test btree-12.5 { - btree_data $::c1 -} $::data -do_test btree-12.6 { - btree_next $::c1 - btree_key $::c1 -} {338} -do_test btree-12.7 { - btree_move_to $::c1 464 - btree_key $::c1 -} {464} -do_test btree-12.8 { - btree_next $::c1 - btree_data $::c1 -} $::data -do_test btree-12.9 { - btree_next $::c1 - btree_key $::c1 -} {466} -do_test btree-12.10 { - btree_move_to $::c1 400 - btree_key $::c1 -} {400} -do_test btree-12.11 { - btree_next $::c1 - btree_data $::c1 -} $::data -do_test btree-12.12 { - btree_next $::c1 - btree_key $::c1 -} {402} -do_test btree-13.1 { - btree_sanity_check $::b1 2 3 -} {} - -# To Do: -# -# 1. Do some deletes from the 3-layer tree -# 2. Commit and reopen the database -# 3. Read every 15th entry and make sure it works -# 4. Implement btree_sanity and put it throughout this script -# - -do_test btree-10.98 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-10.99 { - btree_rollback $::b1 - lindex [btree_pager_stats $::b1] 1 -} {0} -btree_pager_ref_dump $::b1 - -do_test btree-99.1 { - btree_close $::b1 -} {} -catch {unset data} -catch {unset key} - -} ;# end if( not mem: and has pager_open command ); - -finish_test diff --git a/test/btree2.test b/test/btree2.test deleted file mode 100644 index 62874eb7e2..0000000000 --- a/test/btree2.test +++ /dev/null @@ -1,449 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is btree database backend -# -# $Id: btree2.test,v 1.2 2001/07/02 17:51:47 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {$dbprefix!="memory:" && [info commands btree_open]!=""} { - -# Create a new database file containing no entries. The database should -# contain 5 tables: -# -# 2 The descriptor table -# 3 The foreground table -# 4 The background table -# 5 The long key table -# 6 The long data table -# -# An explanation for what all these tables are used for is provided below. -# -do_test btree2-1.1 { - expr srand(1) - file delete -force test2.bt - file delete -force test2.bt-journal - set ::b [btree_open test2.bt] - btree_begin_transaction $::b - btree_create_table $::b -} {3} -do_test btree2-1.2 { - btree_create_table $::b -} {4} -do_test btree2-1.3 { - btree_create_table $::b -} {5} -do_test btree2-1.4 { - btree_create_table $::b -} {6} -do_test btree2-1.5 { - set ::c2 [btree_cursor $::b 2] - btree_insert $::c2 {one} {1} - btree_delete $::c2 - btree_close_cursor $::c2 - btree_commit $::b - btree_sanity_check $::b 2 3 4 5 6 -} {} - -# This test module works by making lots of pseudo-random changes to a -# database while simultaneously maintaining an invariant on that database. -# Periodically, the script does a sanity check on the database and verifies -# that the invariant is satisfied. -# -# The invariant is as follows: -# -# 1. The descriptor table always contains 2 enters. An entry keyed by -# "N" is the number of elements in the foreground and background tables -# combined. The entry keyed by "L" is the number of digits in the keys -# for foreground and background tables. -# -# 2. The union of the foreground an background tables consists of N entries -# where each entry an L-digit key. (Actually, some keys can be longer -# than L characters, but they always start with L digits.) The keys -# cover all integers between 1 and N. Whenever an entry is added to -# the foreground it is removed form the background and vice versa. -# -# 3. Some entries in the foreground and background tables have keys that -# begin with an L-digit number but are followed by additional characters. -# For each such entry there is a corresponding entry in the long key -# table. The long key table entry has a key which is just the L-digit -# number and data which is the length of the key in the foreground and -# background tables. -# -# 4. The data for both foreground and background entries is usually a -# short string. But some entries have long data strings. For each -# such entries there is an entry in the long data type. The key to -# long data table is an L-digit number. (The extension on long keys -# is omitted.) The data is the number of charaters in the data of the -# foreground or background entry. -# -# The following function builds a database that satisfies all of the above -# invariants. -# -proc build_db {N L} { - for {set i 2} {$i<=6} {incr i} { - catch {btree_close_cursor [set ::c$i]} - btree_clear_table $::b $i - set ::c$i [btree_cursor $::b $i] - } - btree_insert $::c2 N $N - btree_insert $::c2 L $L - set format %0${L}d - for {set i 1} {$i<=$N} {incr i} { - set key [format $format $i] - set data $key - btree_insert $::c3 $key $data - } -} - -# Given a base key number and a length, construct the full text of the key -# or data. -# -proc make_payload {keynum L len} { - set key [format %0${L}d $keynum] - set r $key - set i 1 - while {[string length $r]<$len} { - append r " ($i) $key" - incr i - } - return [string range $r 0 [expr {$len-1}]] -} - -# Verify the invariants on the database. Return an empty string on -# success or an error message if something is amiss. -# -proc check_invariants {} { - set ck [btree_sanity_check $::b 2 3 4 5 6] - if {$ck!=""} { - puts "\n*** SANITY:\n$ck" - exit - return $ck - } - btree_move_to $::c3 {} - btree_move_to $::c4 {} - btree_move_to $::c2 N - set N [btree_data $::c2] - btree_move_to $::c2 L - set L [btree_data $::c2] - set LM1 [expr {$L-1}] - for {set i 1} {$i<=$N} {incr i} { - set key [btree_key $::c3] - if {[scan $key %d k]<1} {set k 0} - if {$k!=$i} { - set key [btree_key $::c4] - if {[scan $key %d k]<1} {set k 0} - if {$k!=$i} { - # puts "MISSING $i" - # puts {Page 3:}; btree_page_dump $::b 3 - # puts {Page 4:}; btree_page_dump $::b 4 - # exit - return "Key $i is missing from both foreground and background" - } - set data [btree_data $::c4] - btree_next $::c4 - } else { - set data [btree_data $::c3] - btree_next $::c3 - } - set skey [string range $key 0 $LM1] - if {[btree_move_to $::c5 $skey]==0} { - set keylen [btree_data $::c5] - } else { - set keylen $L - } - if {[string length $key]!=$keylen} { - return "Key $i is the wrong size.\ - Is \"$key\" but should be \"[make_payload $k $L $keylen]\"" - } - if {[make_payload $k $L $keylen]!=$key} { - return "Key $i has an invalid extension" - } - if {[btree_move_to $::c6 $skey]==0} { - set datalen [btree_data $::c6] - } else { - set datalen $L - } - if {[string length $data]!=$datalen} { - return "Data for $i is the wrong size.\ - Is [string length $data] but should be $datalen" - } - if {[make_payload $k $L $datalen]!=$data} { - return "Entry $i has an incorrect data" - } - } -} - -# Make random changes to the database such that each change preserves -# the invariants. The number of changes is $n*N where N is the parameter -# from the descriptor table. Each changes begins with a random key. -# the entry with that key is put in the foreground table with probability -# $I and it is put in background with probability (1.0-$I). It gets -# a long key with probability $K and long data with probability $D. -# -set chngcnt 0 -proc random_changes {n I K D} { - btree_move_to $::c2 N - set N [btree_data $::c2] - btree_move_to $::c2 L - set L [btree_data $::c2] - set LM1 [expr {$L-1}] - set total [expr {int($N*$n)}] - set format %0${L}d - for {set i 0} {$i<$total} {incr i} { - set k [expr {int(rand()*$N)+1}] - set insert [expr {rand()<=$I}] - set longkey [expr {rand()<=$K}] - set longdata [expr {rand()<=$D}] - # incr ::chngcnt - # if {$::chngcnt==251} {btree_tree_dump $::b 3} - # puts "CHANGE $::chngcnt: $k $insert $longkey $longdata" - if {$longkey} { - set x [expr {rand()}] - set keylen [expr {int($x*$x*$x*$x*3000)+10}] - } else { - set keylen $L - } - set key [make_payload $k $L $keylen] - if {$longdata} { - set x [expr {rand()}] - set datalen [expr {int($x*$x*$x*$x*3000)+10}] - } else { - set datalen $L - } - set data [make_payload $k $L $datalen] - set basekey [format $format $k] - if {[set c [btree_move_to $::c3 $basekey]]==0} { - btree_delete $::c3 - } else { - if {$c<0} {btree_next $::c3} - if {[string match $basekey* [btree_key $::c3]]} { - btree_delete $::c3 - } - } - if {[set c [btree_move_to $::c4 $basekey]]==0} { - btree_delete $::c4 - } else { - if {$c<0} {btree_next $::c4} - if {[string match $basekey* [btree_key $::c4]]} { - btree_delete $::c4 - } - } - if {[scan [btree_key $::c4] %d kx]<1} {set kx -1} - if {$kx==$k} { - btree_delete $::c4 - } - if {$insert} { - btree_insert $::c3 $key $data - } else { - btree_insert $::c4 $key $data - } - if {$longkey} { - btree_insert $::c5 $basekey $keylen - } elseif {[btree_move_to $::c5 $basekey]==0} { - btree_delete $::c5 - } - if {$longdata} { - btree_insert $::c6 $basekey $datalen - } elseif {[btree_move_to $::c6 $basekey]==0} { - btree_delete $::c6 - } - # set ck [btree_sanity_check $::b 2 3 4 5 6] - # if {$ck!=""} { - # puts "\nSANITY CHECK FAILED!\n$ck" - # exit - # } - # puts "PAGE 3:"; btree_page_dump $::b 3 - # puts "PAGE 4:"; btree_page_dump $::b 4 - } -} - -# Repeat this test sequence on database of various sizes -# -set testno 2 -foreach {N L} { - 10 2 - 50 2 - 200 3 - 2000 5 -} { - puts "**** N=$N L=$L ****" - set hash [md5file test2.bt] - do_test btree2-$testno.1 [subst -nocommands { - set ::c2 [btree_cursor $::b 2] - set ::c3 [btree_cursor $::b 3] - set ::c4 [btree_cursor $::b 4] - set ::c5 [btree_cursor $::b 5] - set ::c6 [btree_cursor $::b 6] - btree_begin_transaction $::b - build_db $N $L - check_invariants - }] {} - do_test btree2-$testno.2 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - btree_rollback $::b - md5file test2.bt - } $hash - do_test btree2-$testno.3 [subst -nocommands { - btree_begin_transaction $::b - set ::c2 [btree_cursor $::b 2] - set ::c3 [btree_cursor $::b 3] - set ::c4 [btree_cursor $::b 4] - set ::c5 [btree_cursor $::b 5] - set ::c6 [btree_cursor $::b 6] - build_db $N $L - check_invariants - }] {} - do_test btree2-$testno.4 { - btree_commit $::b - check_invariants - } {} - do_test btree2-$testno.5 { - lindex [btree_pager_stats $::b] 1 - } {6} - do_test btree2-$testno.6 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - lindex [btree_pager_stats $::b] 1 - } {0} - do_test btree2-$testno.7 { - btree_close $::b - set ::b [btree_open test2.bt] - set ::c2 [btree_cursor $::b 2] - set ::c3 [btree_cursor $::b 3] - set ::c4 [btree_cursor $::b 4] - set ::c5 [btree_cursor $::b 5] - set ::c6 [btree_cursor $::b 6] - check_invariants - } {} - - # For each database size, run various changes tests. - # - set num2 1 - foreach {n I K D} { - 0.5 0.5 0.1 0.1 - 1.0 0.2 0.1 0.1 - 1.0 0.8 0.1 0.1 - 2.0 0.0 0.1 0.1 - 2.0 1.0 0.1 0.1 - 2.0 0.0 0.0 0.0 - 2.0 1.0 0.0 0.0 - } { - set testid btree2-$testno.8.$num2 - set cnt 6 - for {set i 2} {$i<=6} {incr i} { - if {[lindex [btree_cursor_dump [set ::c$i]] 0]!=$i} {incr cnt} - } - do_test $testid.1 { - btree_begin_transaction $::b - lindex [btree_pager_stats $::b] 1 - } $cnt - set hash [md5file test2.bt] - # exec cp test2.bt test2.bt.bu1 - do_test $testid.2 [subst { - random_changes $n $I $K $D - }] {} - do_test $testid.3 { - check_invariants - } {} - do_test $testid.4 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - btree_rollback $::b - md5file test2.bt - } $hash - # exec cp test2.bt test2.bt.bu2 - btree_begin_transaction $::b - set ::c2 [btree_cursor $::b 2] - set ::c3 [btree_cursor $::b 3] - set ::c4 [btree_cursor $::b 4] - set ::c5 [btree_cursor $::b 5] - set ::c6 [btree_cursor $::b 6] - do_test $testid.5 [subst { - random_changes $n $I $K $D - }] {} - do_test $testid.6 { - check_invariants - } {} - do_test $testid.7 { - btree_commit $::b - check_invariants - } {} - set hash [md5file test2.bt] - do_test $testid.8 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - lindex [btree_pager_stats $::b] 1 - } {0} - do_test $testid.9 { - btree_close $::b - set ::b [btree_open test2.bt] - set ::c2 [btree_cursor $::b 2] - set ::c3 [btree_cursor $::b 3] - set ::c4 [btree_cursor $::b 4] - set ::c5 [btree_cursor $::b 5] - set ::c6 [btree_cursor $::b 6] - check_invariants - } {} - incr num2 - } - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - incr testno -} - -# Testing is complete. Shut everything down. -# -do_test btree-999.1 { - lindex [btree_pager_stats $::b] 1 -} {0} -do_test btree-999.2 { - btree_close $::b -} {} -do_test btree-999.3 { - file delete -force test2.bt - file exists test2.bt-journal -} {0} - -} ;# end if( not mem: and has pager_open command ); - -finish_test diff --git a/test/pager.test b/test/pager.test deleted file mode 100644 index 40777e8c25..0000000000 --- a/test/pager.test +++ /dev/null @@ -1,261 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is page cache subsystem. -# -# $Id: pager.test,v 1.6 2001/06/24 20:39:41 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {$dbprefix!="memory:" && [info commands pager_open]!=""} { - -# Basic sanity check. Open and close a pager. -# -do_test pager-1.0 { - catch {file delete -force ptf1.db} - catch {file delete -force ptf1.db-journal} - set v [catch { - set ::p1 [pager_open ptf1.db 10] - } msg] -} {0} -do_test pager-1.1 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-1.2 { - pager_pagecount $::p1 -} {0} -do_test pager-1.3 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-1.4 { - pager_close $::p1 -} {} - -# Try to write a few pages. -# -do_test pager-2.1 { - set v [catch { - set ::p1 [pager_open ptf1.db 10] - } msg] -} {0} -do_test pager-2.2 { - set v [catch { - set ::g1 [page_get $::p1 0] - } msg] - lappend v $msg -} {1 SQLITE_ERROR} -do_test pager-2.3.1 { - set ::gx [page_lookup $::p1 1] -} {} -do_test pager-2.3.2 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-2.3.3 { - set v [catch { - set ::g1 [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-2.3.3 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.3.4 { - set ::gx [page_lookup $::p1 1] - expr {$::gx!=""} -} {1} -do_test pager-2.3.5 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.3.6 { - expr $::g1==$::gx -} {1} -do_test pager-2.3.7 { - page_unref $::gx - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.4 { - pager_stats $::p1 -} {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} -do_test pager-2.6 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.7 { - page_number $::g1 -} {1} -do_test pager-2.8 { - page_read $::g1 -} {} -do_test pager-2.9 { - page_unref $::g1 -} {} -do_test pager-2.10 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.11 { - set ::g1 [page_get $::p1 1] - expr {$::g1!=0} -} {1} -do_test pager-2.12 { - page_number $::g1 -} {1} -do_test pager-2.13 { - pager_stats $::p1 -} {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" - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.15 { - pager_stats $::p1 -} {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} -do_test pager-2.17 { - set v [catch { - pager_commit $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.20 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 0 miss 2 ovfl 0} -do_test pager-2.19 { - pager_pagecount $::p1 -} {1} -do_test pager-2.21 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 0 miss 2 ovfl 0} -do_test pager-2.22 { - page_unref $::g1 -} {} -do_test pager-2.23 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 2 ovfl 0} -do_test pager-2.24 { - set v [catch { - page_get $::p1 1 - } ::g1] - if {$v} {lappend v $::g1} - set v -} {0} -do_test pager-2.25 { - page_read $::g1 -} {Page-One} -do_test pager-2.26 { - set v [catch { - page_write $::g1 {page-one} - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.27 { - page_read $::g1 -} {page-one} -do_test pager-2.28 { - set v [catch { - pager_rollback $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.29 { - page_read $::g1 -} {Page-One} -do_test pager-2.99 { - pager_close $::p1 -} {} - -do_test pager-3.1 { - set v [catch { - set ::p1 [pager_open ptf1.db 15] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-3.2 { - pager_pagecount $::p1 -} {1} -do_test pager-3.3 { - set v [catch { - set ::g(1) [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-3.4 { - page_read $::g(1) -} {Page-One} -do_test pager-3.5 { - for {set i 2} {$i<=20} {incr i} { - set gx [page_get $::p1 $i] - page_write $gx "Page-$i" - page_unref $gx - } - pager_commit $::p1 -} {} -for {set i 2} {$i<=20} {incr i} { - do_test pager-3.6.[expr {$i-1}] [subst { - set gx \[page_get $::p1 $i\] - set v \[page_read \$gx\] - page_unref \$gx - set v - }] "Page-$i" -} -for {set i 1} {$i<=20} {incr i} { - regsub -all CNT { - set ::g1 [page_get $::p1 CNT] - set ::g2 [page_get $::p1 CNT] - set ::vx [page_read $::g2] - expr {$::g1==$::g2} - } $i body; - do_test pager-3.7.$i.1 $body {1} - regsub -all CNT { - page_unref $::g2 - set vy [page_read $::g1] - expr {$vy==$::vx} - } $i body; - do_test pager-3.7.$i.2 $body {1} - regsub -all CNT { - page_unref $::g1 - set gx [page_get $::p1 CNT] - set vy [page_read $gx] - page_unref $gx - expr {$vy==$::vx} - } $i body; - do_test pager-3.7.$i.3 $body {1} -} -do_test pager-3.99 { - pager_close $::p1 -} {} - - -} ;# end if( not mem: and has pager_open command ); - -finish_test diff --git a/test/quote.test b/test/quote.test new file mode 100644 index 0000000000..98036c5198 --- /dev/null +++ b/test/quote.test @@ -0,0 +1,84 @@ +# Copyright (c) 2001 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 implements regression tests for SQLite library. The +# focus of this file is the ability to specify table and column names +# as quoted strings. +# +# $Id: quote.test,v 1.1 2001/07/23 14:33:04 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Create a table with a strange name and with strange column names. +# +do_test quote-1.0 { + set r [catch { + execsql {CREATE TABLE '@abc' ( '#xyz' int, '!pqr' text );} + } msg] + lappend r $msg +} {0 {}} + +# Insert, update and query the table. +# +do_test quote-1.1 { + set r [catch { + execsql {INSERT INTO '@abc' VALUES(5,'hello')} + } msg] + lappend r $msg +} {0 {}} +do_test quote-1.2 { + set r [catch { + execsql {SELECT * FROM '@abc'} + } msg ] + lappend r $msg +} {0 {5 hello}} +do_test quote-1.3 { + set r [catch { + execsql {SELECT '@abc'.'!pqr', '@abc'.'#xyz'+5 FROM '@abc'} + } msg ] + lappend r $msg +} {0 {hello 10}} +do_test quote-1.4 { + set r [catch { + execsql {UPDATE '@abc' SET '#xyz'=11} + } msg ] + lappend r $msg +} {0 {}} +do_test quote-1.5 { + set r [catch { + execsql {SELECT '@abc'.'!pqr', '@abc'.'#xyz'+5 FROM '@abc'} + } msg ] + lappend r $msg +} {0 {hello 16}} + +# Drop the table with the strange name. +# +do_test quote-1.6 { + set r [catch { + execsql {DROP TABLE '@abc'} + } msg ] + lappend r $msg +} {0 {}} + + +finish_test diff --git a/www/changes.tcl b/www/changes.tcl index 80e34b4e97..17e373b211 100644 --- a/www/changes.tcl +++ b/www/changes.tcl @@ -17,6 +17,13 @@ proc chng {date desc} { puts "

    $desc

" } +chng {2001 Jul 23 (1.0.32)} { +
  • Pager and btree subsystems removed. These will be used in a follow-on + SQL server library named "SQLus".
  • +
  • Add the ability to use quoted strings as table and column names in + expressions.
  • +} + chng {2001 Apr 14 (1.0.31)} {
  • Pager subsystem added but not yet used.
  • More robust handling of out-of-memory errors.