Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Prepare for the 2.5.5 release. (CVS 661) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
00f83c2576f4a9689720d344788f6621 |
User & Date: | drh 2002-07-06 16:32:15.000 |
Context
2002-07-06
| ||
16:34 | Version 2.5.5 (CVS 662) (check-in: 6284c65c17 user: drh tags: trunk) | |
16:32 | Prepare for the 2.5.5 release. (CVS 661) (check-in: 00f83c2576 user: drh tags: trunk) | |
16:28 | Fix for bug #94: Be sure to journal pages that are added to the freelist then removed from the freelist and reused during the same transaction. (CVS 660) (check-in: db178646a0 user: drh tags: trunk) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.5.5 |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.64 2002/07/06 16:32:15 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
2756 2757 2758 2759 2760 2761 2762 | ** Return 1 if there are 2 ore more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ if( iPage==0 ) return 1; | | | 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 | ** Return 1 if there are 2 ore more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ if( iPage==0 ) return 1; if( iPage>pCheck->nPage || iPage<0 ){ char zBuf[100]; sprintf(zBuf, "invalid page number %d", iPage); checkAppendMsg(pCheck, zContext, zBuf); return 1; } if( pCheck->anRef[iPage]==1 ){ char zBuf[100]; |
︙ | ︙ | |||
3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 | nRef = *sqlitepager_stats(pBt->pPager); if( lockBtree(pBt)!=SQLITE_OK ){ return sqliteStrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = sqlitepager_pagecount(sCheck.pPager); sCheck.anRef = sqliteMalloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); sCheck.anRef[1] = 1; for(i=2; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } sCheck.zErrMsg = 0; /* Check the integrity of the freelist */ | > > > > | 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 | nRef = *sqlitepager_stats(pBt->pPager); if( lockBtree(pBt)!=SQLITE_OK ){ return sqliteStrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = sqlitepager_pagecount(sCheck.pPager); if( sCheck.nPage==0 ){ unlockBtreeIfUnused(pBt); return 0; } sCheck.anRef = sqliteMalloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); sCheck.anRef[1] = 1; for(i=2; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } sCheck.zErrMsg = 0; /* Check the integrity of the freelist */ |
︙ | ︙ |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.35 2002/07/06 16:32:15 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
263 264 265 266 267 268 269 | ** The first command opens a connection to the "my_database" database ** and calls that connection "db1". The second command causes this ** subroutine to be invoked. */ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | ** The first command opens a connection to the "my_database" database ** and calls that connection "db1". The second command causes this ** subroutine to be invoked. */ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { "busy", "changes", "close", "complete", "eval", "last_insert_rowid", "open_aux_file", "timeout", 0 }; enum DB_enum { DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMPLETE, DB_EVAL, DB_LAST_INSERT_ROWID, |
︙ | ︙ | |||
699 700 701 702 703 704 705 | Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); for(i=2; i<argc; i++){ Tcl_SetVar(interp, "argv", argv[i], TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); } if( Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ | | | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); for(i=2; i<argc; i++){ Tcl_SetVar(interp, "argv", argv[i], TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); } if( Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); if( zInfo==0 ) zInfo = interp->result; fprintf(stderr,"%s: %s\n", *argv, zInfo); return 1; } }else{ Tcl_GlobalEval(interp, zMainloop); } return 0; } #endif /* TCLSH */ #endif /* !defined(NO_TCL) */ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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.16 2002/07/06 16:32:15 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
63 64 65 66 67 68 69 | int rc; char zBuf[100]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME\"", 0); return TCL_ERROR; } | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 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, 1000, &pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sprintf(zBuf,"%p", pBt); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; |
︙ | ︙ | |||
663 664 665 666 667 668 669 670 671 672 673 674 675 676 | void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ BtCursor *pCur; 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*)&pCur) ) return TCL_ERROR; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ BtCursor *pCur; int rc; int res = 0; 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*)&pCur) ) return TCL_ERROR; rc = sqliteBtreeNext(pCur, &res); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sprintf(zBuf,"%d",res); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; } /* ** Usage: btree_first ID ** ** Move the cursor to the first entry in the table. */ static int btree_first( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ BtCursor *pCur; int rc; int res = 0; 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*)&pCur) ) return TCL_ERROR; rc = sqliteBtreeFirst(pCur, &res); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sprintf(zBuf,"%d",res); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; } /* ** Usage: btree_key ID ** ** Return the key for the entry at which the cursor is pointing. |
︙ | ︙ | |||
753 754 755 756 757 758 759 760 761 762 763 764 765 766 | return TCL_ERROR; } zBuf[n] = 0; Tcl_AppendResult(interp, zBuf, 0); free(zBuf); return SQLITE_OK; } /* ** Usage: btree_cursor_dump ID ** ** Return eight integers containing information about the entry the ** cursor is pointing to: ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | return TCL_ERROR; } zBuf[n] = 0; Tcl_AppendResult(interp, zBuf, 0); free(zBuf); return SQLITE_OK; } /* ** Usage: btree_payload_size ID ** ** Return the number of bytes of payload */ static int btree_payload_size( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ BtCursor *pCur; int n1, n2; char zBuf[50]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR; sqliteBtreeKeySize(pCur, &n1); sqliteBtreeDataSize(pCur, &n2); sprintf(zBuf, "%d", n1+n2); Tcl_AppendResult(interp, zBuf, 0); free(zBuf); return SQLITE_OK; } /* ** Usage: btree_cursor_dump ID ** ** Return eight integers containing information about the entry the ** cursor is pointing to: ** |
︙ | ︙ | |||
828 829 830 831 832 833 834 835 836 837 838 839 840 | Tcl_CreateCommand(interp, "btree_close_cursor", btree_close_cursor, 0, 0); Tcl_CreateCommand(interp, "btree_move_to", btree_move_to, 0, 0); Tcl_CreateCommand(interp, "btree_delete", btree_delete, 0, 0); Tcl_CreateCommand(interp, "btree_insert", btree_insert, 0, 0); Tcl_CreateCommand(interp, "btree_next", btree_next, 0, 0); Tcl_CreateCommand(interp, "btree_key", btree_key, 0, 0); Tcl_CreateCommand(interp, "btree_data", btree_data, 0, 0); Tcl_CreateCommand(interp, "btree_cursor_dump", btree_cursor_dump, 0, 0); Tcl_CreateCommand(interp, "btree_integrity_check", btree_integrity_check,0,0); Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable, TCL_LINK_INT); return TCL_OK; } | > > | 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | Tcl_CreateCommand(interp, "btree_close_cursor", btree_close_cursor, 0, 0); Tcl_CreateCommand(interp, "btree_move_to", btree_move_to, 0, 0); Tcl_CreateCommand(interp, "btree_delete", btree_delete, 0, 0); Tcl_CreateCommand(interp, "btree_insert", btree_insert, 0, 0); Tcl_CreateCommand(interp, "btree_next", btree_next, 0, 0); Tcl_CreateCommand(interp, "btree_key", btree_key, 0, 0); Tcl_CreateCommand(interp, "btree_data", btree_data, 0, 0); Tcl_CreateCommand(interp, "btree_payload_size", btree_payload_size, 0, 0); Tcl_CreateCommand(interp, "btree_first", btree_first, 0, 0); Tcl_CreateCommand(interp, "btree_cursor_dump", btree_cursor_dump, 0, 0); Tcl_CreateCommand(interp, "btree_integrity_check", btree_integrity_check,0,0); Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable, TCL_LINK_INT); return TCL_OK; } |
Added tool/diffdb.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* ** A utility for printing the differences between two SQLite database files. */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #define PAGESIZE 1024 static int db1 = -1; static int db2 = -1; int main(int argc, char **argv){ int iPg; unsigned char a1[PAGESIZE], a2[PAGESIZE]; if( argc!=3 ){ fprintf(stderr,"Usage: %s FILENAME FILENAME\n", argv[0]); exit(1); } db1 = open(argv[1], O_RDONLY); if( db1<0 ){ fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); exit(1); } db2 = open(argv[2], O_RDONLY); if( db2<0 ){ fprintf(stderr,"%s: can't open %s\n", argv[0], argv[2]); exit(1); } iPg = 1; while( read(db1, a1, PAGESIZE)==PAGESIZE && read(db2,a2,PAGESIZE)==PAGESIZE ){ if( memcmp(a1,a2,PAGESIZE) ){ printf("Page %d\n", iPg); } iPg++; } printf("%d pages checked\n", iPg-1); close(db1); close(db2); } |
Added tool/showdb.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | /* ** A utility for printing all or part of an SQLite database file. */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> static int pagesize = 1024; static int db = -1; static int mxPage = 0; static void out_of_memory(void){ fprintf(stderr,"Out of memory...\n"); exit(1); } static print_page(int iPg){ unsigned char *aData; int i, j; aData = malloc(pagesize); if( aData==0 ) out_of_memory(); lseek(db, (iPg-1)*pagesize, SEEK_SET); read(db, aData, pagesize); fprintf(stdout, "Page %d:\n", iPg); for(i=0; i<pagesize; i += 16){ fprintf(stdout, " %03x: ",i); for(j=0; j<16; j++){ fprintf(stdout,"%02x ", aData[i+j]); } for(j=0; j<16; j++){ fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); } fprintf(stdout,"\n"); } free(aData); } int main(int argc, char **argv){ struct stat sbuf; if( argc<2 ){ fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]); exit(1); } db = open(argv[1], O_RDONLY); if( db<0 ){ fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); exit(1); } fstat(db, &sbuf); mxPage = sbuf.st_size/pagesize + 1; if( argc==2 ){ int i; for(i=1; i<=mxPage; i++) print_page(i); }else{ int i; for(i=2; i<argc; i++){ int iStart, iEnd; char *zLeft; iStart = strtol(argv[i], &zLeft, 0); if( zLeft && strcmp(zLeft,"..end")==0 ){ iEnd = mxPage; }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){ iEnd = strtol(&zLeft[2], 0, 0); }else{ iEnd = iStart; } if( iStart<1 || iEnd<iStart || iEnd>mxPage ){ fprintf(stderr, "Page argument should be LOWER?..UPPER?. Range 1 to %d\n", mxPage); exit(1); } while( iStart<=iEnd ){ print_page(iStart); iStart++; } } } close(db); } |
Added tool/showjournal.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | /* ** A utility for printing an SQLite database journal. */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> static int pagesize = 1024; static int db = -1; static int mxPage = 0; static void out_of_memory(void){ fprintf(stderr,"Out of memory...\n"); exit(1); } static print_page(int iPg){ unsigned char *aData; int i, j; aData = malloc(pagesize); if( aData==0 ) out_of_memory(); read(db, aData, pagesize); fprintf(stdout, "Page %d:\n", iPg); for(i=0; i<pagesize; i += 16){ fprintf(stdout, " %03x: ",i); for(j=0; j<16; j++){ fprintf(stdout,"%02x ", aData[i+j]); } for(j=0; j<16; j++){ fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); } fprintf(stdout,"\n"); } free(aData); } int main(int argc, char **argv){ struct stat sbuf; unsigned int u; int rc; char zBuf[100]; if( argc!=2 ){ fprintf(stderr,"Usage: %s FILENAME\n", argv[0]); exit(1); } db = open(argv[1], O_RDONLY); if( db<0 ){ fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); exit(1); } read(db, zBuf, 8); read(db, &u, sizeof(u)); printf("Database Size: %u\n", u); while( read(db, &u, sizeof(u))==sizeof(u) ){ print_page(u); } close(db); } |
Changes to www/changes.tcl.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2002 Jly 1 (2.5.4)} { <li>Make the "AS" keyword optional again.</li> <li>The datatype of columns now appear in the 4th argument to the callback.</li> <li>Added the <b>sqlite_open_aux_file()</b> API, though it is still mostly undocumented and untested.</li> | > > > > > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2002 Jly 6 (2.5.5)} { <li>Fix a bug which could cause database corruption during a rollback. This bugs was introduced in version 2.4.0 by the freelist optimization of checking [410].</li> <li>Fix a bug in aggregate functions for VIEWs.</li> <li>Other minor changes and enhancements.</li> } chng {2002 Jly 1 (2.5.4)} { <li>Make the "AS" keyword optional again.</li> <li>The datatype of columns now appear in the 4th argument to the callback.</li> <li>Added the <b>sqlite_open_aux_file()</b> API, though it is still mostly undocumented and untested.</li> |
︙ | ︙ |