]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
:-) (CVS 84)
authordrh <drh@noemail.net>
Thu, 8 Jun 2000 19:38:36 +0000 (19:38 +0000)
committerdrh <drh@noemail.net>
Thu, 8 Jun 2000 19:38:36 +0000 (19:38 +0000)
FossilOrigin-Name: 57dce04addf6389a0e2b723aea47da6a54bff14e

Makefile.in
manifest
manifest.uuid
www/fileformat.tcl [new file with mode: 0644]
www/index.tcl
www/sqlite.tcl

index c02d5dd168eac12357ee9375ac97404fbfde80a6..c0ec4641c72292d781f3558e4f775af36bfa7779 100644 (file)
@@ -182,6 +182,9 @@ c_interface.html:   $(TOP)/www/c_interface.tcl
 changes.html:  $(TOP)/www/changes.tcl
        tclsh $(TOP)/www/changes.tcl >changes.html
 
+fileformat.html:       $(TOP)/www/fileformat.tcl
+       tclsh $(TOP)/www/fileformat.tcl >fileformat.html
+
 # Files to be published on the website.
 #
 PUBLISH = \
@@ -189,6 +192,7 @@ PUBLISH = \
   index.html \
   sqlite.html \
   changes.html \
+  fileformat.html \
   c_interface.html
 
 website:       $(PUBLISH)
index 2cf1b1cf483fb3acfadc00f53068825e69d3d8fd..f44d86e147d85ca4f30919fce3a88227804ba9d7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,7 +1,7 @@
-C :-)\s(CVS\s83)
-D 2000-06-08T16:54:40
+C :-)\s(CVS\s84)
+D 2000-06-08T19:38:36
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
-F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
+F Makefile.in 078af767c0d9e00d47b5d2b6e7677a10445d7057
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
 F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
 F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
@@ -55,9 +55,10 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
 F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
 F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
-F www/index.tcl 52e29a4eeda8d59e91af43c61fef177c5f2ffd53
-F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
-P 33355b2d8d23b51e917961b7fb336bc1d454497f
-R 698c786702799109c8590452a815b490
+F www/fileformat.tcl b11435fcd2cf2238a1c5e6d16fe5e83bcd14d434
+F www/index.tcl b2c288000f14383501b157a57ee4506561d62f45
+F www/sqlite.tcl 2e11809cd69dcf002042b455ef43c312beb3a00f
+P 2e5786d10148872db47d99e39c3f54597ad777c8
+R f81bf38bfc7dc6081b5aa2efb83f3693
 U drh
-Z e88522b8c3d025e67d3ca5bc0fce8783
+Z a2dd5ae39f552f2d8fffe430ca60ae6e
index 358969967ef8e4e557a746cf8f83188099721112..2b414f0de99c77d0243804e11742286caf09fbb7 100644 (file)
@@ -1 +1 @@
-2e5786d10148872db47d99e39c3f54597ad777c8
\ No newline at end of file
+57dce04addf6389a0e2b723aea47da6a54bff14e
\ No newline at end of file
diff --git a/www/fileformat.tcl b/www/fileformat.tcl
new file mode 100644 (file)
index 0000000..5cb4506
--- /dev/null
@@ -0,0 +1,218 @@
+#
+# Run this Tcl script to generate the fileformat.html file.
+#
+set rcsid {$Id: fileformat.tcl,v 1.1 2000/06/08 19:38:36 drh Exp $}
+
+puts {<html>
+<head>
+  <title>The SQLite file format</title>
+</head>
+<body bgcolor=white>
+<h1 align=center>
+The SQLite File Format
+</h1>}
+puts "<p align=center>
+(This page was last modified on [lrange $rcsid 3 4] GMT)
+</p>"
+
+puts {
+<p>SQLite stores each SQL table and index in a separate GDBM file.
+The name of the GDBM file used to store a particular table is usually
+just the table name with "<b>.tbl</b>" appended.
+Consider an example:</p>
+}
+
+proc Code {body} {
+  puts {<blockquote><pre>}
+  regsub -all {&} [string trim $body] {\&amp;} body
+  regsub -all {>} $body {\&gt;} body
+  regsub -all {<} $body {\&lt;} body
+  regsub -all {\(\(\(} $body {<font color="#00671f"><i>} body
+  regsub -all {\)\)\)} $body {</i></font>} body
+  puts $body
+  puts {</pre></blockquote>}
+}
+
+Code {
+$ (((rm -rf ex1)))
+$ (((sqlite ex1)))
+Enter ".help" for instructions
+sqlite> (((create table tbl1(one varchar(10), two smallint);)))
+sqlite> (((create index idx1 on tbl1(one);)))
+sqlite> (((insert into tbl1 values('hello!',10);)))
+sqlite> (((.exit)))
+$ ls ex1
+idx1.tbl  sqlite_master.tbl  tbl1.tbl
+$
+}
+
+puts {
+<p>The example above creates a new SQL database with a single
+table named <b>tbl1</b> and a single index named <b>idx1</b>.
+Three files were created for this database.  <b>tbl1.tbl</b> stores
+all the data for the <b>tbl1</b> table and <b>idx1.tbl</b> stores
+all the information needed by the index <b>idx1</b>.  The remaining file
+<b>sqlite_master.tbl</b> holds the data for the special
+built-in table called <b>sqlite_master</b>.  Every SQLite database
+has an <b>sqlite_master</b> table.  This table contains the schema
+for the database.  You can query the <b>sqlite_master</b> table
+using ordinary SQL commands, but you cannot write to the
+<b>sqlite_master</b> table.</p>
+
+<p>The GDBM file used to store an SQL table is <em>usually</em>
+just the name of the table with <b>.tbl</b> appended.  But there
+are exceptions.  First, the name of the table is converted to
+all lower case letters before being used to construct the filename.
+This is because SQL table names are not case sensitive but Unix filenames are.
+Second, if the table name contains any characters other than 
+alphanumerics and underscores, the exceptional characters are encoded
+as a single '+' sign.  For example:</p>
+}
+
+Code {
+$ (((sqlite ex1)))
+sqlite> (((create table 'Strange Table Name!'(a int, b char(30));)))
+sqlite> .exit
+$ (((ls ex1)))
+idx1.tbl sqlite_master.tbl strange+table+name+.tbl tbl1.tbl
+$
+}
+
+puts {
+<h2>SQL Table File Format</h2>
+
+<p>Each record of a GDBM file contains a key and a data.
+Both key and data are arbitary bytes of any length.  The information
+from an SQL table is mapped into a GDBM file as follows:</p>
+
+<p>The GDBM key for each record of an SQL table file is a
+randomly chosen integer.  The key size thus depends on the size
+of an integer on the host computer.  (Typically this means "4 bytes".)
+</p>
+
+<p>If the SQL table contains N columns, then the data entry
+for each record begins with N integers.  Each integer is the
+offset in bytes from the beginning of the GDBM data to the 
+start of the data for the corresponding column.  If the column
+contains a NULL value, then its corresponding integer will
+be zero.  All column data is stored as null-terminated ASCII
+text strings.</p>
+
+<p>Consider a simple example:</p>
+}
+
+Code {
+$ (((rm -rf ex1)))
+$ (((sqlite ex1)))
+sqlite> (((create table t1(a int, b text, c text);)))
+sqlite> (((insert into t1 values(10,NULL,'hello!');)))
+sqlite> (((insert into t1 values(-11,'this is','a test');)))
+sqlite> (((.exit)))
+$ (((gdbmdump ex1/t1.tbl)))
+key  : 223100ae                                      "1..
+data : 0c000000 10000000 18000000 2d313100 74686973  ............-11.this
+       20697300 61207465 737400                       is.a test.
+
+key  : a840e996                                      .@..
+data : 0c000000 00000000 0f000000 31300068 656c6c6f  ............10.hello
+       2100                                          !.
+
+$
+}
+
+puts {
+<p>In the example above, we have created a new table named <b>t1</b>
+that contains two records. The <b>gdbmdump</b> program is used to
+dump the contents of the <b>t1</b> GDBM file
+in a human readable format.  The source code to <b>gdbmdump</b>
+is included with the SQLite distribution.  Just type "make gdbmdump"
+to build it.</p>
+
+<p>We can see in the dump of <b>t1</b> that each record
+is a separate GDBM entry with a 4-byte random key.  The keys
+shown are for a single sample run. If you try
+this experiment yourself, you will probably get completely different
+keys.<p>
+
+<p>Because the <b>t1</b> table contains 3 columns, the data part of
+each record begins with 3 integers.  In both records of the example,
+the first integer
+has the value 12 since the beginning of the data for the first column
+begins on the 13th byte of the record.  You can see how each column's
+data is stored as a null-terminated string.  For the second record,
+observe that the offset integer is zero for the second column.  This
+indicates that the second column contains NULL data.</p>
+
+<h2>SQL Index File Format</h2>
+
+<p>Each SQL index is also represented using a single GDBM file.
+There is one entry in the GDBM file for each unique SQL key in the
+table that is being indexed.  The GDBM key is an
+arbitrary length null-terminated string which is SQL key that
+is used by the index.  The data is a list of integers that correspond
+to GDBM keys of entries in data table that have the corresponding
+SQL key.</p>
+
+<p>To illustrate, we will create an index on the example table
+shown above, and add a new entry to this table that has a duplicate
+SQL key.</p>
+}
+
+Code {
+$ (((sqlite ex1)))
+sqlite> (((create index i1 on t1(a);)))
+sqlite> (((insert into t1 values(10,'another','record');)))
+sqlite> (((.exit)))
+$ (((gdbmdump ex1/t1.tbl)))
+key  : 223100ae                                      "1..
+data : 0c000000 10000000 18000000 2d313100 74686973  ............-11.this
+       20697300 61207465 737400                       is.a test.
+
+key  : a840e996                                      .@..
+data : 0c000000 00000000 0f000000 31300068 656c6c6f  ............10.hello
+       2100                                          !.
+
+key  : c19e3119                                      ..1.
+data : 0c000000 0f000000 17000000 31300061 6e6f7468  ............10.anoth
+       65720072 65636f72 6400                        er.record.
+$
+}
+
+puts {
+<p>We added the new record to the <b>t1</b> table because we wanted to
+have two records with the same value on column <b>a</b> since that
+column is used by the <b>i1</b> index.  You can see from the dump
+above that the new <b>t1</b> record is assigned another random
+GDBM key.</p>
+
+<p>Now let's look at a dump of the index file.</p>
+}
+
+Code {
+$ (((gdbmdump ex1/i1.tbl)))
+key  : 313000                                        10.
+data : a840e996 c19e3119                             .@....1.
+
+key  : 2d313100                                      -11.
+data : 223100ae                                      "1..
+
+$
+}
+
+puts {
+<p>The GDBM file for the index contains only two records because
+the <b>t1</b> table contains only two distinct values for
+column <b>a</b>.  You can see that the GDBM keys for each record
+are just the text values for <b>a</b> columns of table <b>t1</b>.
+The data for each record of the index is a list of integers
+where each integer is the GDBM key for an entry in the <b>t1</b>
+table that has the corresponding value for the <b>a</b> column.</p>
+}
+
+puts {
+<p><hr /></p>
+<p><a href="index.html"><img src="/goback.jpg" border=0 />
+Back to the SQLite Home Page</a>
+</p>
+
+</body></html>}
index 705a8bb0e2c306535b1587d3ade19edf50ffcc83..e2e59aa64e48c3f5218647d91393b993a5a20050 100644 (file)
@@ -1,18 +1,19 @@
 #
 # Run this TCL script to generate HTML for the index.html file.
 #
-set rcsid {$Id: index.tcl,v 1.14 2000/06/06 22:19:02 drh Exp $}
+set rcsid {$Id: index.tcl,v 1.15 2000/06/08 19:38:36 drh Exp $}
 
 puts {<html>
-<head><title>SQLite: An SQL Database Built Atop GDBM</title></head>
+<head><title>SQLite: An SQL Database Engine Built Atop GDBM</title></head>
 <body bgcolor=white>
-<h1 align=center>SQLite: An SQL Database Built Upon 
+<h1 align=center>SQLite: An SQL Database Engine Built Atop
 <a href="http://www.gnu.org/software/gdbm/gdbm.html">GDBM</a></h1>
 <p align=center>}
 puts "This page was last modified on [lrange $rcsid 3 4] GMT<br>"
 puts "The SQLite source code was last modifed on [exec cat last_change] GMT"
 puts {</p>}
 
+if 0 {
 puts {
 <h2>News</h2>
 <p>
@@ -27,56 +28,77 @@ There are currently no known errors in the code.</p>
 <p>If you find bugs or missing features, please submit a comment
 to the <a href="#mailinglist">SQLite mailing list</a>.</p>
 }
+}
 
 puts {<h2>Introduction</h2>
 
-<p>SQLite is an SQL database built atop the 
+<p>SQLite is an SQL database engine built on top of the
 <a href="http://www.gnu.org/software/gdbm/gdbm.html">GDBM library</a>.
-The SQLite distribution includes both a interactive command-line
-access program (<b>sqlite</b>) and a C library (<b>libsqlite.a</b>)
+SQLite includes a standalone command-line
+access program (<a href="sqlite.html">sqlite</a>)
+and a C library (<a href="c_interface.html">libsqlite.a</a>)
 that can be linked
-with a C/C++ program to provide SQL database access without having
-to rely on an external RDBMS.</p>
-
-<p>The C interface to SQLite is very simple, consisting of only
-four functions, a single opaque data structure, and a handful of
-constants that define error return codes.
-See <a href="c_interface.html">c_interface.html</a> for details.
-A Tcl interface
-to SQLite is also available and is included in the source tree.
-Documentation on the Tcl interface is pending.
-Interfaces for perl and python may be supplied in future releases.</p>
-
-<p>The standalone program <b>sqlite</b> can be used
-to interactively create, update and/or query an SQLite database.
-The sources to the sqlite program are part of the source tree and
-can be used as an example of how to interact with the SQLite C
-library.  For more information on the sqlite program,
-see <a href="sqlite.html">sqlite.html</a>.</p>
-
-<p>A history of changes to SQLite is found
-<a href="changes.html">here</a>.</p>
-
-<p>SQLite now implements most of the SQL language.
-The following are the known limitations:</p>
+with a C/C++ program to provide SQL database access without
+an separate RDBMS.</p>
+
+<h2>Features</h2>
+
+<p><ul>
+<li>Implements most of SQL92.</li>
+<li>A database is just a directory of GDBM files.</li>
+<li>Unlimited length records.</li>
+<li>Import and export data from 
+<a href="http://www.postgresql.org/">PostgreSQL</a>.</li>
+<li>Very simple 
+<a href="c_interface.html">C/C++ interface</a> uses only
+four functions and one opaque structure.</li>
+<li>A <a href="http://dev.scriptics.com/">Tcl</a> interface is
+included.</li>
+<li>Command-line access program <a href="sqlite.html">sqlite</a> uses
+the <a href="http://www.google.com/search?q=gnu+readline+library">GNU
+Readline library</a></li>
+<li>A Tcl-based test suite provides near 100% code coverage</li>
+<li>7500+ lines of C code.  No external dependencies other than GDBM.</li>
+<li>Built and tested under Linux (RedHat 6.0).  Should work under any Unix and
+probably also under Windows95/98/NT/2000.</li>
+</ul>
+</p>
+
+<h2>Current Status</h2>
+
+<p>A <a href="changes.html">change history</a> is available online.
+There are currently no <em>known</em> bugs or memory leaks
+in the library.  <a href="http://gcc.gnu.org/onlinedocs/gcov_1.html">Gcov</a>
+is used to verify test coverage.  The test suite currently exercises
+all code except for a few areas which are unreachable or which are
+only reached when <tt>malloc()</tt> fails.  The code has been tested
+for memory leaks and is found to be clean.</p>
+
+<p>
+Among the SQL features that SQLite does not currently implement are:</p>
 
 <p>
 <ul>
-<li>Constraints are parsed but are not enforced</li>
-<li>There is no support for transactions or rollback</li>
+<li>outer joins</li>
+<li>constraints are parsed but are not enforced</li>
+<li>no support for transactions or rollback</li>
 </ul>
 </p>
 
-<H2>Status</h2>
+<h2>Documentation</h2>
 
-<p>New features are still being added to the SQLite code base.
-Nevertheless, the code appears to be stable and relatively
-bug-free. At least one large database has
-be loaded into SQLite and appears to work.</p>
+<p>The following documentation is currently available:</p>
 
-<p>SQLite has so far been tested only on RedHat 6.0 Linux.  But we
-know of no reason why it will not work on any other Unix platform,
-or on Windows95/98/NT.</p>
+<p><ul>
+<li>Information on the <a href="sqlite.html">sqlite</a>
+    command-line utility.</li>
+<li>The <a href="c_interface.html">C/C++ Interface</a>.</li>
+<li>The <a href="fileformat.html">file format</a> used by SQLite databases.</li>
+</ul>
+</p>
+
+<p>The SQLite source code is 35% comment.  These comments are
+another important source of information. </p>
 }
 
 puts {
@@ -104,15 +126,41 @@ build directory, run configure from the build directory and then
 type "make".  For example:</p>
 
 <blockquote><pre>
-$ tar xzf sqlite.tar.gz   ;# Unpacks into directory named "sqlite"
-$ mkdir bld               ;# Create a separate build directory
+$ tar xzf sqlite.tar.gz      <i> Unpacks into directory named "sqlite" </i>
+$ mkdir bld                  <i> Create a separate build directory </i>
 $ cd bld
 $ ../sqlite/configure
-$ make                    ;# Builds "sqlite" and "libsqlite.a"
-$ make test               ;# Optional: run regression tests
+$ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
+$ make test                  <i> Optional: run regression tests </i>
 </pre></blockquote>
 }
 
+puts {<h2>Command-line Usage Example</h2>
+
+<p>Download the source archive and compile the <b>sqlite</b>
+program as described above.  The type:</p>
+
+<blockquote><pre>
+bash$ sqlite ~/newdb              <i>Directory ~/newdb created automatically</i>
+sqlite> create table t1(
+   ...>    a int,
+   ...>    b varchar(20)
+   ...>    c text
+   ...> );                        <i>End each SQL statement with a ';'</i>
+sqlite> insert into t1
+   ...> values(1,'hi','y''all');
+sqlite> select * from t1;
+1|hello|world
+sqlite> .mode columns             <i>Special commands begin with '.'</i>
+sqlite> .header on                <i>Type ".help" for a list of commands</i>
+sqlite> select * from t1;
+a      b       c
+------ ------- -------
+1      hi      y'all
+sqlite> .exit
+base$
+</pre></blockquote>
+}
 puts {<h2>Related Sites</h2>
 
 <ul>
index d0cd62849ac317701e4f76a6fd4cf627ed84b294..51d398a482221a70ea5ca1a8e6bc10a270f68ab5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: sqlite.tcl,v 1.6 2000/06/02 13:28:00 drh Exp $}
+set rcsid {$Id: sqlite.tcl,v 1.7 2000/06/08 19:38:36 drh Exp $}
 
 puts {<html>
 <head>
@@ -52,13 +52,13 @@ Code {
 $ (((mkdir ex1)))
 $ (((sqlite ex1)))
 Enter ".help" for instructions
-sql> (((create table tbl1(one varchar(10), two smallint);)))
-sql> (((insert into tbl1 values('hello!',10);)))
-sql> (((insert into tbl1 values('goodbye', 20);)))
-sql> (((select * from tbl1;)))
+sqlite> (((create table tbl1(one varchar(10), two smallint);)))
+sqlite> (((insert into tbl1 values('hello!',10);)))
+sqlite> (((insert into tbl1 values('goodbye', 20);)))
+sqlite> (((select * from tbl1;)))
 hello!|10
 goodbye|20
-sql>
+sqlite>
 }
 
 puts {
@@ -79,12 +79,12 @@ enter SQL commands that span multiple lines.  For example:</p>
 }
 
 Code {
-sql> (((CREATE TABLE tbl2 ()))
-.... (((  f1 varchar(30) primary key,)))
-.... (((  f2 text,)))
-.... (((  f3 real)))
-.... ((();)))
-sql> 
+sqlite> (((CREATE TABLE tbl2 ()))
+   ...> (((  f1 varchar(30) primary key,)))
+   ...> (((  f2 text,)))
+   ...> (((  f3 real)))
+   ...> ((();)))
+sqlite
 }
 
 puts {
@@ -108,12 +108,12 @@ in an SQLite database.  For example:</p>
 Code {
 $ (((sqlite ex1)))
 Enter ".help" for instructions
-sql> (((select * from sqlite_master;)))
+sqlite> (((select * from sqlite_master;)))
 type = table
 name = tbl1
 tbl_name = tbl1
 sql = create table tbl1(one varchar(10), two smallint)
-sql>
+sqlite>
 }
 
 puts {
@@ -142,7 +142,8 @@ at any time.  For example:
 </p>}
 
 Code {
-sql> (((.help)))
+sqlite> (((.help)))
+.dump                  Dump database in a text format
 .exit                  Exit this program
 .explain               Set output mode suitable for EXPLAIN
 .header ON|OFF         Turn display of headers on or off
@@ -155,7 +156,7 @@ sql> (((.help)))
 .separator STRING      Change separator string for "list" mode
 .tables                List names all tables in the database
 .width NUM NUM ...     Set column widths for "column" mode
-sql> 
+sqlite
 }
 
 puts {
@@ -166,6 +167,35 @@ in four different formats: "line", "column", "list", and "html".
 You can use the ".mode" dot command to switch between these three output
 formats.</p>
 
+puts {
+<p>The default output mode is "list".  In
+list mode, each record of a query result is written on one line of
+output and each field within that record is separated by a specific
+separator string.  The default separator is a pipe symbol ("|").
+List mode is especially useful when you are going to send the output
+of a query to another program (such as AWK) for additional processing.</p>}
+
+Code {
+sqlite> (((.mode list)))
+sqlite> (((select * from tbl1;)))
+hello|10
+goodbye|20
+sqlite>
+}
+
+puts {
+<p>You can use the ".separator" dot command to change the separator
+for list mode.  For example, to change the separator to a comma and
+a space, you could do this:</p>}
+
+Code {
+sqlite> (((.separator ", ")))
+sqlite> (((select * from tbl1;)))
+hello, 10
+goodbye, 20
+sqlite>
+}
+
 <p>In "line" mode, each field in a record of the database
 is shown on a line by itself.  Each line consists of the field
 name, an equal sign and the field data.  Successive records are
@@ -173,20 +203,14 @@ separated by a blank line.  Here is an example of line mode
 output:</p>}
 
 Code {
-sql> (((.mode line)))
-sql> (((select * from tbl1;)))
+sqlite> (((.mode line)))
+sqlite> (((select * from tbl1;)))
 one = hello
 two = 10
 
 one = goodbye
 two = 20
-sql>
-}
-
-puts {
-<p>Line mode used to be the default mode setting.  But after some
-experience using the utility, it was decided that "list" mode made
-a better default and so now the default mode is "list".</p>
+sqlite>
 }
 
 puts {
@@ -194,13 +218,13 @@ puts {
 data aligned in columns.  For example:</p>}
 
 Code {
-sql> (((.mode column)))
-sql> (((select * from tbl1;)))
+sqlite> (((.mode column)))
+sqlite> (((select * from tbl1;)))
 one         two       
 ----------  ----------
 hello       10        
 goodbye     20        
-sql>
+sqlite>
 }
 
 puts {
@@ -209,13 +233,13 @@ Data that is too wide to fit in a column is truncated.  You can
 adjust the column widths using the ".width" command.  Like this:</p>}
 
 Code {
-sql> (((.width 12 6)))
-sql> (((select * from tbl1;)))
+sqlite> (((.width 12 6)))
+sqlite> (((select * from tbl1;)))
 one           two   
 ------------  ------
 hello         10    
 goodbye       20    
-sql>
+sqlite>
 }
 
 puts {
@@ -231,40 +255,11 @@ examples above, the column labels are on.  To turn them off you
 could do this:</p>}
 
 Code {
-sql> (((.header off)))
-sql> (((select * from tbl1;)))
+sqlite> (((.header off)))
+sqlite> (((select * from tbl1;)))
 hello         10    
 goodbye       20    
-sql>
-}
-
-puts {
-<p>The third output mode supported by sqlite is called "list".  In
-list mode, each record of a query result is written on one line of
-output and each field within that record is separated by a specific
-separator string.  The default separator is a pipe symbol ("|").
-List mode is especially useful when you are going to send the output
-of a query to another program (such as AWK) for additional processing.</p>}
-
-Code {
-sql> (((.mode list)))
-sql> (((select * from tbl1;)))
-hello|10
-goodbye|20
-sql>
-}
-
-puts {
-<p>You can use the ".separator" dot command to change the separator
-for list mode.  For example, to change the separator to a comma and
-a space, you could do this:</p>}
-
-Code {
-sql> (((.separator ", ")))
-sql> (((select * from tbl1;)))
-hello, 10
-goodbye, 20
-sql>
+sqlite>
 }
 
 puts {
@@ -286,11 +281,11 @@ query results will be written to that file.  Use ".output stdout" to
 begin writing to standard output again.  For example:</p>}
 
 Code {
-sql> (((.mode list)))
-sql> (((.separator |)))
-sql> (((.output test_file_1.txt)))
-sql> (((select * from tbl1;)))
-sql> (((.exit)))
+sqlite> (((.mode list)))
+sqlite> (((.separator |)))
+sqlite> (((.output test_file_1.txt)))
+sqlite> (((select * from tbl1;)))
+sqlite> (((.exit)))
 $ (((cat test_file_1.txt)))
 hello|10
 goodbye|20
@@ -310,10 +305,10 @@ can enter ".tables".</p>
 }
 
 Code {
-sql> (((.tables)))
+sqlite> (((.tables)))
 tbl1
 tbl2
-sql>
+sqlite>
 }
 
 puts {
@@ -341,20 +336,20 @@ CREATE statement used to make that table and all if its indices.
 We have:</p>}
 
 Code {
-sql> (((.schema)))
+sqlite> (((.schema)))
 create table tbl1(one varchar(10), two smallint)
 CREATE TABLE tbl2 (
   f1 varchar(30) primary key,
   f2 text,
   f3 real
 )
-sql> (((.schema tbl2)))
+sqlite> (((.schema tbl2)))
 CREATE TABLE tbl2 (
   f1 varchar(30) primary key,
   f2 text,
   f3 real
 )
-sql>
+sqlite>
 }
 
 puts {
@@ -378,6 +373,60 @@ ORDER BY type DESC, name
 <p>The <b>%s</b> in the query above is replaced by the argument
 to ".schema", of course.</p>
 
+<h2>Converting An Entire Database To An ASCII Text File</h2>
+
+<p>Use the ".dump" command to convert the entire contents of a
+database into a single ASCII text file.  This file can be converted
+back into a database by piping it back into <b>sqlite</b>.</p>
+
+<p>A good way to make an archival copy of a database is this:</p>
+}
+
+Code {
+$ (((echo '.dump' | sqlite ex1 | gzip -c >ex1.dump.gz)))
+}
+
+puts {
+<p>This generates a file named <b>ex1.dump.gz</b> that contains everything
+you need to reconstruct the database at a later time, or on another
+machine.  To reconstruct the database, just type:</p>
+}
+
+Code {
+$ (((zcat ex1.dump.gz | sqlite ex2)))
+}
+
+puts {
+<p>The text format used is the same as used by
+<a href="http://www.postgresql.org/">PostgreSQL</a>, so you
+can also use the .dump command to export an SQLite database
+into a PostgreSQL database.  Like this:</p>
+}
+
+Code {
+$ (((createdb ex2)))
+$ (((echo '.dump' | sqlite ex1 | psql ex2)))
+}
+
+puts {
+<p>You can almost (but not quite) go the other way and export
+a PostgreSQL database into SQLite using the <b>pg_dump</b> utility.
+Unfortunately, when <b>pg_dump</b> writes the database schema information,
+it uses some SQL syntax that SQLite does not understand.
+So you cannot pipe the output of <b>pg_dump</b> directly 
+into <b>sqlite</b>.
+But if you can recreate the
+schema separately, you can use <b>pg_dump</b> with the <b>-a</b>
+option to list just the data
+of a PostgreSQL database and import that directly into SQLite.</p>
+}
+
+Code {
+$ (((sqlite ex3 <schema.sql)))
+$ (((pg_dump -a ex2 | sqlite ex3)))
+}
+
+puts {
 <h2>Other Dot Commands</h2>
 
 <p>The ".explain" dot command can be used to set the output mode
@@ -390,8 +439,8 @@ instructions that would have been used to execute the SQL command are
 returned like a query result.  For example:</p>}
 
 Code {
-sql> (((.explain)))
-sql> (((explain delete from tbl1 where two<20;)))
+sqlite> (((.explain)))
+sqlite> (((explain delete from tbl1 where two<20;)))
 addr  opcode        p1     p2     p3          
 ----  ------------  -----  -----  -------------------------------------   
 0     ListOpen      0      0