/ Check-in [34c4149e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Updates prior to release 2.6.3. (CVS 706)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:34c4149eea7a48927e36867f4e25ff7fac40c66e
User & Date: drh 2002-08-13 00:01:17
Context
2002-08-13
00:02
Version 2.6.3 (CVS 707) check-in: ba706aca user: drh tags: trunk
00:01
Updates prior to release 2.6.3. (CVS 706) check-in: 34c4149e user: drh tags: trunk
2002-08-12
12:29
Fix for ticket #9 (again). The rollback journal files should now also be byte-order independent. (CVS 705) check-in: 2fb3fdcd user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.template.

153
154
155
156
157
158
159

160
161
162
163
164
165
166
  $(TOP)/src/vdbe.h \
  $(TOP)/src/where.c

# Source code to the test files.
#
TESTSRC = \
  $(TOP)/src/btree.c \

  $(TOP)/src/os.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/test1.c \
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/md5.c








>







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  $(TOP)/src/vdbe.h \
  $(TOP)/src/where.c

# Source code to the test files.
#
TESTSRC = \
  $(TOP)/src/btree.c \
  $(TOP)/src/func.c \
  $(TOP)/src/os.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/test1.c \
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/md5.c

Changes to VERSION.

1
2.6.2
|
1
2.6.3

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
72
73
74
75
76
77
78


79
80
81
82
83
84
85
...
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
** 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.69 2002/08/11 20:10:47 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.
................................................................................
** native byte order or in non-native byte order.  Non-native byte order
** databases are created for testing purposes only.  Under normal operation,
** only native byte-order databases should be created, but we should be
** able to read or write existing databases regardless of the byteorder.
*/
#ifdef SQLITE_TEST
int btree_native_byte_order = 1;


#endif

/*
** Forward declarations of structures used only in this file.
*/
typedef struct PageOne PageOne;
typedef struct MemPage MemPage;
................................................................................
  if( rc ) return rc;
  rc = sqlitepager_write(pRoot);
  if( rc ){
    sqlitepager_unref(pRoot);
    return rc;
  }
  strcpy(pP1->zMagic, zMagicHeader);
#ifdef SQLITE_TEST
  if( btree_native_byte_order ){
    pP1->iMagic = MAGIC;
    pBt->needSwab = 0;
  }else{
    pP1->iMagic = swab32(MAGIC);
    pBt->needSwab = 1;
  }
#else
  pP1->iMagic = MAGIC;
  pBt->needSwab = 0;
#endif
  zeroPage(pBt, pRoot);
  sqlitepager_unref(pRoot);
  return SQLITE_OK;
}

/*
** Attempt to start a new transaction.







|







 







>
>







 







<







<
<
<
<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
791
792
793
794
795
796
797

798
799
800
801
802
803
804




805
806
807
808
809
810
811
** 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.70 2002/08/13 00:01:17 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.
................................................................................
** native byte order or in non-native byte order.  Non-native byte order
** databases are created for testing purposes only.  Under normal operation,
** only native byte-order databases should be created, but we should be
** able to read or write existing databases regardless of the byteorder.
*/
#ifdef SQLITE_TEST
int btree_native_byte_order = 1;
#else
# define btree_native_byte_order 1
#endif

/*
** Forward declarations of structures used only in this file.
*/
typedef struct PageOne PageOne;
typedef struct MemPage MemPage;
................................................................................
  if( rc ) return rc;
  rc = sqlitepager_write(pRoot);
  if( rc ){
    sqlitepager_unref(pRoot);
    return rc;
  }
  strcpy(pP1->zMagic, zMagicHeader);

  if( btree_native_byte_order ){
    pP1->iMagic = MAGIC;
    pBt->needSwab = 0;
  }else{
    pP1->iMagic = swab32(MAGIC);
    pBt->needSwab = 1;
  }




  zeroPage(pBt, pRoot);
  sqlitepager_unref(pRoot);
  return SQLITE_OK;
}

/*
** Attempt to start a new transaction.

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
478
479
480
481
482
483
484



485

486
487
488
489
490
491
492
....
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
....
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.50 2002/08/12 12:29:57 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
/*
** The following integer, if set, causes journals to be written in the
** old format.  This is used for testing purposes only - to make sure
** the code is able to rollback an old journal.
*/
#ifdef SQLITE_TEST
int pager_old_format = 0;


#endif

/*
** Hash a page number
*/
#define pager_hash(PN)  ((PN)%N_PG_HASH)

/*
** Enable reference count tracking here:
*/
#if SQLITE_TEST
  int pager_refinfo_enable = 0;
  static void pager_refinfo(PgHdr *p){
    static int cnt = 0;
    if( !pager_refinfo_enable ) return;
    printf(
       "REFCNT: %4d addr=0x%08x nRef=%d\n",
       p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
................................................................................

/*
** Write a 32-bit integer into the given file descriptor.  Writing
** is always done using the new journal format.
*/
static int write32bits(OsFile *fd, u32 val){
  unsigned char ac[4];
#ifdef SQLITE_TEST
  if( pager_old_format ){
    return sqliteOsWrite(fd, &val, 4);
  }
#endif
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
  return sqliteOsWrite(fd, ac, 4);
}

................................................................................
    goto end_ckpt_playback;
  }
  nRec /= sizeof(PageRecord);
  
  /* Copy original pages out of the checkpoint journal and back into the
  ** database file.
  */



  pPager->journalFormat = SQLITE_NEW_JOURNAL_FORMAT;

  for(i=nRec-1; i>=0; i--){
    rc = pager_playback_one_page(pPager, &pPager->cpfd);
    if( rc!=SQLITE_OK ) goto end_ckpt_playback;
  }

  /* Figure out how many pages need to be copied out of the transaction
  ** journal.
................................................................................
    pPager->journalOpen = 1;
    pPager->needSync = 0;
    pPager->dirtyFile = 0;
    pPager->alwaysRollback = 0;
    pPager->state = SQLITE_WRITELOCK;
    sqlitepager_pagecount(pPager);
    pPager->origDbSize = pPager->dbSize;
#ifdef SQLITE_TEST
    if( pager_old_format ){
      rc = sqliteOsWrite(&pPager->jfd, aOldJournalMagic,
                         sizeof(aOldJournalMagic));
    }else{
      rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
    }
#else
    rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
#endif
    if( rc==SQLITE_OK ){
      rc = write32bits(&pPager->jfd, pPager->dbSize);
    }
    if( rc!=SQLITE_OK ){
      rc = pager_unwritelock(pPager);
      if( rc==SQLITE_OK ) rc = SQLITE_FULL;
    }
................................................................................
    sqlitepager_ckpt_commit(pPager);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

#if SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlitepager_refdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    printf("PAGE %3d addr=0x%08x nRef=%d\n", 
       pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif







|







 







>
>










|







 







<



<







 







>
>
>
|
>







 







<






<
<
<







 







|












14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
223
224
225
226
227
228
229

230
231
232

233
234
235
236
237
238
239
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
....
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152



1153
1154
1155
1156
1157
1158
1159
....
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.51 2002/08/13 00:01:17 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
/*
** The following integer, if set, causes journals to be written in the
** old format.  This is used for testing purposes only - to make sure
** the code is able to rollback an old journal.
*/
#ifdef SQLITE_TEST
int pager_old_format = 0;
#else
# define pager_old_format 0
#endif

/*
** Hash a page number
*/
#define pager_hash(PN)  ((PN)%N_PG_HASH)

/*
** Enable reference count tracking here:
*/
#ifdef SQLITE_TEST
  int pager_refinfo_enable = 0;
  static void pager_refinfo(PgHdr *p){
    static int cnt = 0;
    if( !pager_refinfo_enable ) return;
    printf(
       "REFCNT: %4d addr=0x%08x nRef=%d\n",
       p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
................................................................................

/*
** Write a 32-bit integer into the given file descriptor.  Writing
** is always done using the new journal format.
*/
static int write32bits(OsFile *fd, u32 val){
  unsigned char ac[4];

  if( pager_old_format ){
    return sqliteOsWrite(fd, &val, 4);
  }

  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
  return sqliteOsWrite(fd, ac, 4);
}

................................................................................
    goto end_ckpt_playback;
  }
  nRec /= sizeof(PageRecord);
  
  /* Copy original pages out of the checkpoint journal and back into the
  ** database file.
  */
  if( pager_old_format ){
    pPager->journalFormat = SQLITE_OLD_JOURNAL_FORMAT;
  }else{
    pPager->journalFormat = SQLITE_NEW_JOURNAL_FORMAT;
  }
  for(i=nRec-1; i>=0; i--){
    rc = pager_playback_one_page(pPager, &pPager->cpfd);
    if( rc!=SQLITE_OK ) goto end_ckpt_playback;
  }

  /* Figure out how many pages need to be copied out of the transaction
  ** journal.
................................................................................
    pPager->journalOpen = 1;
    pPager->needSync = 0;
    pPager->dirtyFile = 0;
    pPager->alwaysRollback = 0;
    pPager->state = SQLITE_WRITELOCK;
    sqlitepager_pagecount(pPager);
    pPager->origDbSize = pPager->dbSize;

    if( pager_old_format ){
      rc = sqliteOsWrite(&pPager->jfd, aOldJournalMagic,
                         sizeof(aOldJournalMagic));
    }else{
      rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
    }



    if( rc==SQLITE_OK ){
      rc = write32bits(&pPager->jfd, pPager->dbSize);
    }
    if( rc!=SQLITE_OK ){
      rc = pager_unwritelock(pPager);
      if( rc==SQLITE_OK ) rc = SQLITE_FULL;
    }
................................................................................
    sqlitepager_ckpt_commit(pPager);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlitepager_refdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    printf("PAGE %3d addr=0x%08x nRef=%d\n", 
       pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif

Changes to test/trans.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
882
883
884
885
886
887
888

889
890
891
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: trans.test,v 1.14 2002/08/12 12:29:57 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Create several tables to work with.
................................................................................
  if {$i<$limit} {
    do_test trans-9.$i.9-$cnt {
       execsql {
         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
       }
    } {}
  }

}
   
finish_test







|







 







>



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
882
883
884
885
886
887
888
889
890
891
892
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: trans.test,v 1.15 2002/08/13 00:01:18 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Create several tables to work with.
................................................................................
  if {$i<$limit} {
    do_test trans-9.$i.9-$cnt {
       execsql {
         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
       }
    } {}
  }
  set ::pager_old_format 0
}
   
finish_test

Changes to test/trigger2.test.

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
    INSERT INTO tbl VALUES(100, 200, 300);
  }
  db changes
} {1}
execsql {
  DROP TABLE tbl;
}


# Handling of ON CONFLICT by INSERT statements inside triggers
execsql {
  CREATE TABLE tbl (a primary key, b, c);
  CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
  END;







<







425
426
427
428
429
430
431

432
433
434
435
436
437
438
    INSERT INTO tbl VALUES(100, 200, 300);
  }
  db changes
} {1}
execsql {
  DROP TABLE tbl;
}


# Handling of ON CONFLICT by INSERT statements inside triggers
execsql {
  CREATE TABLE tbl (a primary key, b, c);
  CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
  END;

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 30 (2.6.2)} {
<li>Text files read by the COPY command can now have line terminators
    of LF,  CRLF, or CR.</li>
<li>SQLITE_BUSY is handled correctly if encountered during database
    initialization.</li>
<li>Fix to UPDATE triggers on TEMP tables.</li>







>
>
>
>
>
>
>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2002 Aug 12 (2.6.3)} {
<li>Add the ability to read both little-endian and big-endian databases.
    So database created under SunOS or MacOSX can be read and written
    under Linux or Windows and vice versa.</li>
<li>Convert to the new website: http://www.sqlite.org/</li>
<li>Allow transactions to span Linux Threads</li>
<li>Bug fix in the processing of the ORDER BY clause for GROUP BY queries</li>
}

chng {2002 Jly 30 (2.6.2)} {
<li>Text files read by the COPY command can now have line terminators
    of LF,  CRLF, or CR.</li>
<li>SQLITE_BUSY is handled correctly if encountered during database
    initialization.</li>
<li>Fix to UPDATE triggers on TEMP tables.</li>

Changes to www/index.tcl.

1
2
3
4
5
6
7
8
9
10
11
..
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
121
122
123
124
125
126
127
128

















129
130
131
132
133
134
135
136
...
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213

214
215
216
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.62 2002/08/12 12:29:58 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] UTC<br>"
................................................................................
}

puts {<h2>Features</h2>

<p><ul>
<li>Implements most of SQL92.</li>
<li>A complete database (with multiple tables and indices) is
    stored in a single byte-order independent disk file.</li>
<li>Atomic commit and rollback protect data integrity.</li>


<li>Small memory footprint: less than 20K lines of C code.</li>
<li><a href="speed.html">Four times faster</a> than PostgreSQL.
    Twice as fast as SQLite 1.0.</li>
<li>Very simple 
<a href="c_interface.html">C/C++ interface</a> requires the use of only
three functions and one opaque structure.</li>
<li><a href="tclsqlite.html">TCL bindings</a> included.</li>

<li>A TCL-based test suite provides near 100% code coverage.</li>
<li>Self-contained: no external dependencies.</li>
<li>Built and tested under Linux and Win2K.</li>
<li>Sources are uncopyrighted.  Use for any purpose.</li>
</ul>
</p>
}

puts {<h2>Database File Format Change - 2002 July 17</h2>

<p>Beginning with version 2.6.0, the SQLite database file format changed
in an incompatible way.  If you open a database file from version 2.5.6
or earlier with version 2.6.0 or later of the library, then the file format
will be converted automatically.  This is an irreversible operation.  Once
the conversion occurs, you will no longer be able to access the database
file from older versions of the library.  If the database is large, the
conversion might take some time. (Allow 1 to 2 seconds per megabyte
of database under Linux.) If the database is read-only,
the conversion cannot occur and the attempt to open the database will
fail.
It is suggested that you make backup copies of older database files
before attempting to open them with version 2.6.0 or later of the library.</p>

<center>
<table width="50%" border=1 cellpadding=20 cellspacing=0>
<tr><td>
<b>Make backups of older database files before opening them
with version 2.6.0 or later of SQLite</b></td></tr>
</table>
</center>
}

puts {<h2>Current Status</h2>

<p>A <a href="changes.html">Change Summary</a> is available on this
website.  You can also access a detailed
<a href="http://cvs.hwaci.com:2080/sqlite/timeline">change history</a>,
<a href="http://cvs.hwaci.com:2080/sqlite/rptview?rn=2">view open bugs</a>,
or
................................................................................

<p>
Whenever either of the first two digits in the version number
for SQLite change, it means that the underlying file format
has changed.  See <a href="formatchng.html">formatchng.html</a>
for additional information.
</p>


















<h2>Documentation</h2>

<p>The following documentation is currently available:</p>

<p><ul>
<li><a href="faq.html">Frequently Asked Questions</a> are available online.</li>
<li>Information on the <a href="sqlite.html">sqlite</a>
    command-line utility.</li>
................................................................................
$ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
$ make test                  <i> Optional: run regression tests </i>
</pre></blockquote>
}

puts {<h2>Related Sites</h2>

<ul>


<li><p>An ODBC driver for SQLite can be found at
       <a href="http://www.ch-werner.de/sqliteodbc/">
       http://www.ch-werner.de/sqliteodbc/</a>.</p></li>

<li><p>A PHP module for SQLite can be found at
       <a href="http://freshmeat.net/projects/sqlite-php">
       http://freshmeat.net/projects/sqlite-php</a></li>
</ul>}


puts {
</body></html>}



|







 







|

>
>
|






>








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|
<
>
|
|
|

|
|
|
|
>



1
2
3
4
5
6
7
8
9
10
11
..
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
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.63 2002/08/13 00:01:18 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] UTC<br>"
................................................................................
}

puts {<h2>Features</h2>

<p><ul>
<li>Implements most of SQL92.</li>
<li>A complete database (with multiple tables and indices) is
    stored in a single disk file.</li>
<li>Atomic commit and rollback protect data integrity.</li>
<li>Database files can be freely shared between machines with
    different byte orders.</li>
<li>Small memory footprint: less than 25K lines of C code.</li>
<li><a href="speed.html">Four times faster</a> than PostgreSQL.
    Twice as fast as SQLite 1.0.</li>
<li>Very simple 
<a href="c_interface.html">C/C++ interface</a> requires the use of only
three functions and one opaque structure.</li>
<li><a href="tclsqlite.html">TCL bindings</a> included.</li>
<li>Simple, well-commented source code.</li>
<li>A TCL-based test suite provides near 100% code coverage.</li>
<li>Self-contained: no external dependencies.</li>
<li>Built and tested under Linux and Win2K.</li>
<li>Sources are uncopyrighted.  Use for any purpose.</li>
</ul>
</p>
}

























puts {<h2>Current Status</h2>

<p>A <a href="changes.html">Change Summary</a> is available on this
website.  You can also access a detailed
<a href="http://cvs.hwaci.com:2080/sqlite/timeline">change history</a>,
<a href="http://cvs.hwaci.com:2080/sqlite/rptview?rn=2">view open bugs</a>,
or
................................................................................

<p>
Whenever either of the first two digits in the version number
for SQLite change, it means that the underlying file format
has changed.  See <a href="formatchng.html">formatchng.html</a>
for additional information.
</p>
}

puts {<h2>Database File Format Change - Version 2.6.0 - 2002 July 17</h2>

<p>Beginning with version 2.6.0, the SQLite database file format changed
in an incompatible way.  If you open a database file from version 2.5.6
or earlier with version 2.6.0 or later of the library, then the file format
will be converted automatically.  This is an irreversible operation.  Once
the conversion occurs, you will no longer be able to access the database
file from older versions of the library.  If the database is large, the
conversion might take some time. (Allow 1 to 2 seconds per megabyte
of database under Linux.) If the database is read-only,
the conversion cannot occur and the attempt to open the database will
fail.
It is suggested that you make backup copies of older database files
before attempting to open them with version 2.6.0 or later of the library.</p>
}

puts {<h2>Documentation</h2>

<p>The following documentation is currently available:</p>

<p><ul>
<li><a href="faq.html">Frequently Asked Questions</a> are available online.</li>
<li>Information on the <a href="sqlite.html">sqlite</a>
    command-line utility.</li>
................................................................................
$ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
$ make test                  <i> Optional: run regression tests </i>
</pre></blockquote>
}

puts {<h2>Related Sites</h2>

<p>

For information bindings of SQLite to other programming languages
(Perl, Python, Ruby, PHP, etc.) and for a list of programs currently
using SQLite, visit the Wiki documentation at:
</p>

<blockquote>
<a href="http://cvs.hwaci.com:2080/sqlite/wiki">
http://cvs.hwaci.com:2080/sqlite/wiki</a>
</blockquote>
}

puts {
</body></html>}