]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
:-) (CVS 2)
authordrh <drh@noemail.net>
Mon, 29 May 2000 17:44:25 +0000 (17:44 +0000)
committerdrh <drh@noemail.net>
Mon, 29 May 2000 17:44:25 +0000 (17:44 +0000)
FossilOrigin-Name: 53841c66c699665e83c933627bbe7a193cfccb6b

Makefile.in
manifest
manifest.uuid
src/build.c
src/shell.c
src/util.c
www/index.tcl [new file with mode: 0644]
www/sqlite.tcl [new file with mode: 0644]

index 5e9db181844ea798554fc14316e6a72398116cb7..3084140289037dfd3b6e7170695ac21714f7f715 100644 (file)
@@ -44,14 +44,14 @@ LIBOBJ = build.o dbbe.o main.o parse.o tokenize.o util.o vdbe.o where.o
 # This is the default Makefile target.  The objects listed here
 # are what get build when you type just "make" with no arguments.
 #
-all:   libsqlite.a sqlite
+all:   libsqlite.a sqlite.h sqlite
 # libtclsqlite.a tclsqlite
 
 libsqlite.a:   $(LIBOBJ)
        $(AR) libsqlite.a $(LIBOBJ)
        $(RANLIB) libsqlite.a
 
-sqlite:        $(TOP)/src/shell.c libsqlite.a $(TOP)/src/sqlite.h
+sqlite:        $(TOP)/src/shell.c libsqlite.a sqlite.h
        $(TCC) $(READLINE_FLAGS) -o sqlite $(TOP)/src/shell.c \
                libsqlite.a $(LIBGDBM) $(LIBREADLINE)
 
@@ -88,6 +88,9 @@ parse.c:      $(TOP)/src/parse.y lemon
        cp $(TOP)/src/parse.y .
        ./lemon parse.y
 
+sqlite.h:      $(TOP)/src/sqlite.h
+       cp $(TOP)/src/sqlite.h .
+
 tokenize.o:    $(TOP)/src/tokenize.c $(HDR)
        $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/tokenize.c
 
@@ -100,6 +103,24 @@ vdbe.o:    $(TOP)/src/vdbe.c $(HDR)
 where.o:       $(TOP)/src/where.c $(HDR)
        $(TCC) $(GDBM_FLAGS) -c $(TOP)/src/where.c
 
+TARBALL = \
+  sqlite/doc/*.html \
+  sqlite/src/*.h \
+  sqlite/src/*.c \
+  sqlite/tool/*.c \
+  sqlite/tool/*.awk \
+  sqlite/configure \
+  sqlite/*.in
+
+sqlite.tar.gz: 
+       pwd=`pwd`; cd $(TOP)/..; tar czf $$pwd/sqlite.tar.gz $(TARBALL)
+
+index.html:    $(TOP)/www/index.tcl sqlite.tar.gz
+       tclsh $(TOP)/www/index.tcl >index.html
+
+sqlite.html:   $(TOP)/www/sqlite.tcl
+       tclsh $(TOP)/www/sqlite.tcl >sqlite.html
+
 clean: 
-       rm -f *.o sqlite libsqlite.a
-       rm -f lemon lempar.c parse.*
+       rm -f *.o sqlite libsqlite.a sqlite.h
+       rm -f lemon lempar.c parse.* sqlite.tar.gz
index a2d479053a83618df6e04200accf2f67a47e2bbf..0c0a0a7dcb57c77031b217465b3631c3f2eaf76c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,19 +1,19 @@
-C initial\scheck-in\sof\sthe\snew\sversion\s(CVS\s1)
-D 2000-05-29T14:26:00
-F Makefile.in 4bd5c67a3a2816e930df4b22df8c1631ee87ff0c
+C :-)\s(CVS\s2)
+D 2000-05-29T17:44:25
+F Makefile.in bab6ff58d847d1b9eb25d4cbf671e4ebd0c74256
 F configure 8faba4d0194321e5f61a64e842c65eab0f68e6d8 x
 F configure.in 4fc2947d631037bd340b112d6193847d7ac827ae
 F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
-F src/build.c 64016990ebbbcbc848165551732a1f9f397bd150
+F src/build.c 45dc91016e13dec70620b049a53ba785b4a0c76b
 F src/dbbe.c ab05293e89525041eaab8b4aca10516db3648792
 F src/dbbe.h bedeb3a0985bb584458e7849fb59927e99e751e6
 F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f
-F src/shell.c de770d16aae1ea219e7a9ab5147a4437c23b4a6c
+F src/shell.c 125f84ea5f8b725ba474d4702b575d062cc94d92
 F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69
 F src/sqliteInt.h 0365970442441b5e9b74e1e828afdeac7b0662be
 F src/tclsqlite.c 6eca1c1b8713048245d295ed18dca71c91d4931f
 F src/tokenize.c ab578d90ec6ab117b7ade6e6cfbcb5b0f9cad500
-F src/util.c 370c2339bb9ff82645804a4c62506149392fd032
+F src/util.c b2e2a4dc55f7cbd41a7d9e0a8473eedd3b2691c8
 F src/vdbe.c 80132b6bb9a744d1990a1c16666d54baaff2dbc3
 F src/vdbe.h e721ad308f2e6ca805cebc4dd0a196ce4419d030
 F src/where.c 67ffea57920e16b33c580e9a9b9855b3ec9dea7b
@@ -23,7 +23,9 @@ F tool/lempar.c a1eec94d6eacc12332368660ec65f3b248853833
 F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
-P 704b122e5308587b60b47a5c2fff40c593d4bf8f
-R 33c985d67f2f41286bc65b8529a1ae84
+F www/index.tcl 3785d894fe5fc0976bb7400ab307b4aef34fbf60
+F www/sqlite.tcl c24416391358ade2e74fffeaca8eb0b0e8b1d1ac
+P 6f3655f79f9b6fc9fb7baaa10a7e0f2b6a512dfa
+R 6b1f63772187c94801897db097691461
 U drh
-Z a9e2b0f2d67c72179e4ea5172821c6d6
+Z 084e3a79b4f63a91b5e2b285235fe69b
index 1fff0226d4de6571158b8e4ee1b896236b1eca5a..6a331145080d2d7b1022cba365d095bf9409a3f4 100644 (file)
@@ -1 +1 @@
-6f3655f79f9b6fc9fb7baaa10a7e0f2b6a512dfa
\ No newline at end of file
+53841c66c699665e83c933627bbe7a193cfccb6b
\ No newline at end of file
index ba4eb170dae334ac69160a5caed8f0dd64e359ec..ad0fec58c52e6f4a663405329f39b1a3023bc037 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** when syntax rules are reduced.
 **
-** $Id: build.c,v 1.1 2000/05/29 14:26:01 drh Exp $
+** $Id: build.c,v 1.2 2000/05/29 17:44:25 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -243,7 +243,7 @@ void sqliteAddColumn(Parse *pParse, Token *pName){
   char **pz;
   if( (p = pParse->pNewTable)==0 ) return;
   if( (p->nCol & 0x7)==0 ){
-    p->azCol = sqliteRealloc( p->azCol, p->nCol+8);
+    p->azCol = sqliteRealloc( p->azCol, (p->nCol+8)*sizeof(p->azCol[0]));
   }
   if( p->azCol==0 ){
     p->nCol = 0;
@@ -288,9 +288,9 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
       { OP_Open,        0, 0, MASTER_NAME },
       { OP_New,         0, 0, 0},
       { OP_String,      0, 0, "table"     },
-      { OP_String,      0, 0, 0},            /* 2 */
       { OP_String,      0, 0, 0},            /* 3 */
       { OP_String,      0, 0, 0},            /* 4 */
+      { OP_String,      0, 0, 0},            /* 5 */
       { OP_MakeRecord,  4, 0, 0},
       { OP_Put,         0, 0, 0},
       { OP_Close,       0, 0, 0},
@@ -304,9 +304,9 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
     if( v==0 ) return;
     n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1;
     base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable);
-    sqliteVdbeChangeP3(v, base+2, p->zName, 0);
     sqliteVdbeChangeP3(v, base+3, p->zName, 0);
-    sqliteVdbeChangeP3(v, base+4, pParse->sFirstToken.z, n);
+    sqliteVdbeChangeP3(v, base+4, p->zName, 0);
+    sqliteVdbeChangeP3(v, base+5, pParse->sFirstToken.z, n);
   }
 }
 
index 08127474573a09bffaf1bc0eb27ac129d965b244..c0cfa1f3e2368ee26e1986397c324ec175a436f7 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains code to implement the "sqlite" command line
 ** utility for accessing SQLite databases.
 **
-** $Id: shell.c,v 1.1 2000/05/29 14:26:01 drh Exp $
+** $Id: shell.c,v 1.2 2000/05/29 17:44:25 drh Exp $
 */
 #include <stdlib.h>
 #include <string.h>
@@ -221,7 +221,8 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
     data.showHeader = 0;
     data.mode = MODE_List;
     sprintf(zSql, "SELECT name FROM sqlite_master "
-                  "WHERE type='index' AND tbl_name='%.900s'", azArg[1]);
+                  "WHERE type='index' AND tbl_name='%.00s' "
+                  "ORDER BY name", azArg[1]);
     sqlite_exec(db, zSql, callback, &data, &zErrMsg);
     if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);
@@ -283,7 +284,8 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
   if( c=='t' && strncmp(azArg[0], "tables", n)==0 ){
     struct callback_data data;
     char *zErrMsg = 0;
-    static char zSql[] = "SELECT name FROM sqlite_master WHERE type='table'";
+    static char zSql[] = 
+      "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
     memcpy(&data, p, sizeof(data));
     data.showHeader = 0;
     data.mode = MODE_List;
@@ -344,6 +346,7 @@ int main(int argc, char **argv){
       );
     }
     while( (zLine = readline(istty ? (zSql==0 ? "sql> " : ".... ") : 0))!=0 ){
+      add_history(zLine);
       if( zLine && zLine[0]=='.' ){
         do_meta_command(zLine, db, &data);
         free(zLine);
index 130634547ed61c1a6d4a348eeb742a15d59b678a..78fadd2fea1d68d2ce76e90c5fd321a9fbfb8a7d 100644 (file)
@@ -26,7 +26,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.1 2000/05/29 14:26:02 drh Exp $
+** $Id: util.c,v 1.2 2000/05/29 17:44:25 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -38,6 +38,7 @@
 */
 void *sqliteMalloc(int n){
   void *p = malloc(n);
+  /* printf("alloc 0x%x size: %d bytes\n", (int)p, n); */
   if( p==0 ) return 0;
   memset(p, 0, n);
   return p;
@@ -47,7 +48,10 @@ void *sqliteMalloc(int n){
 ** Free memory previously obtained from sqliteMalloc()
 */
 void sqliteFree(void *p){
-  if( p ) free(p);
+  if( p ){
+    /* printf("free 0x%x\n", (int)p); */
+    free(p);
+  }
 }
 
 /*
diff --git a/www/index.tcl b/www/index.tcl
new file mode 100644 (file)
index 0000000..082d0a5
--- /dev/null
@@ -0,0 +1,118 @@
+#
+# Run this TCL script to generate HTML for the index.html file.
+#
+set rcsid {$Id: index.tcl,v 1.1 2000/05/29 17:44:25 drh Exp $}
+
+puts {<html>
+<head><title>SQLite: An SQL Frontend For GDBM</title></head>
+<body bgcolor=white>
+<h1 align=center>SQLite: An SQL Frontend For GDBM</h1>
+<p align=center>}
+puts "Version 0.1 (alpha)<br />"
+puts "Last modified [lrange $rcsid 3 4]"
+puts {</p>}
+
+puts {<h2>Introduction</h2>
+
+<p>SQLite is a C library that implements an SQL frontend to GDBM.
+SQLite is intended for use in standalone programs that need 
+to use an SQL database but which do not have access to a full-blown 
+SQL RDBMS.</p>
+
+<p>The C interface to SQLite is very simple, consisting of only
+four functions and a single opaque data structure.  A Tcl interface
+to SQLite is also available and is included in the source tree.
+Interfaces for perl and python may be supplied in future releases.</p>
+
+<p>There is a standalone C program named "sqlite" that 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.</p>
+
+<p>SQLite does not try to implement every feature of SQL.  But it
+does strive to implement to most commonly used features.  SQLite
+currently understands the following SQL commands:</p>
+
+<p>
+<ul>
+<li>CREATE TABLE</li>
+<li>CREATE INDEX</li>
+<li>DROP TABLE</li>
+<li>DROP INDEX</li>
+<li>INSERT INTO</li>
+<li>UPDATE</li>
+<li>SELECT</li>
+<li>DELETE FROM</li>
+</ul>
+</p>
+
+<p>SQLite does not (at present) implement any of these features:</p>
+
+<p>
+<ul>
+<li>ALTER TABLE</li>
+<li>The GROUP BY or HAVING clauses of a SELECT</li>
+<li>The LIKE or IN operators of expressions</li>
+<li>Constraints</li>
+<li>Transactions or rollback</li>
+</ul>
+</p>
+
+<H2>Status</h2>
+
+<p>The current version of SQLite should be considered "alpha" software.
+It is incomplete and is known to contain bugs.  The software is
+subject to incompatible changes with each release.  You should not use
+SQLite in its present form in production software.</p>
+
+<p>The purpose of releasing SQLite before it is ready is to evoke
+public comment and criticism of the software.  If you find bugs
+or have any thoughts on how to make SQLite better, or would
+like to contribute code or patches to SQLite, please join
+the mailing (see below) and let us know.</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>
+}
+
+puts {<h2>Mailing List</h2>
+<p>A mailing list has been set up on eGroups for discussion of
+SQLite design issues or for asking questions about SQLite.</p>
+<center>
+<a href="http://www.egroups.com/subscribe/sqlite">
+<img src="http://www.egroups.com/img/ui/join.gif" border=0 /><br />
+Click to subscribe to sqlite</a>
+</center>}
+
+puts {<h2>Download</h2>
+
+<p>You can download a tarball containing complete SQLite source
+code at <a href="sqlite.tar.gz">sqlite.tar.gz</a>.}
+puts "This is a [file size sqlite.tar.gz] byte download.  The
+tarball was last modified at [clock format [file mtime sqlite.tar.gz]]"
+puts {</p>}
+
+puts {<h2>Related Sites</h2>
+
+<ul>
+<li><p>The cannonical site for GDBM is
+       <a href="http://www.gnu.org/software/gdbm/gdbm.html">
+       http://www.gnu.org/software/gdbm/gdbm.html</a></p></li>
+
+<li><p>Someday, we would like to port SQLite to work with
+       the Berkeley DB library in addition to GDBM.  For information
+       about the Berkeley DB library, see
+       <a href="http://www.sleepcat.com/">http://www.sleepycat.com</a>
+       </p></li>
+</ul>}
+
+puts {
+<p><hr /></p>
+<p>
+<a href="../index.html"><img src="/goback.jpg" border=0 />
+More Open Source Software</a> from Hwaci.
+</p>
+
+</body></html>}
diff --git a/www/sqlite.tcl b/www/sqlite.tcl
new file mode 100644 (file)
index 0000000..5183a38
--- /dev/null
@@ -0,0 +1,431 @@
+#
+# Run this Tcl script to generate the sqlite.html file.
+#
+set rcsid {$Id: sqlite.tcl,v 1.1 2000/05/29 17:44:26 drh Exp $}
+
+puts {<html>
+<head>
+  <title>sqlite: A program of interacting with SQLite databases</title>
+</head>
+<body bgcolor=white>
+<h1 align=center>
+<tt>sqlite</tt>: A program to administer SQLite databases
+</h1>}
+puts "<p align=center>(This page was last modified on [lrange $rcsid 3 4])</p>"
+
+puts {
+<p>The SQLite library includes a simple command-line utility named
+<b>sqlite</b> that allows the user to manually enter and execute SQL
+commands against an SQLite database.  This document provides a brief
+introduction on how to use <b>sqlite</b>.
+
+<h2>Getting Started</h2>
+
+<p>To start the <b>sqlite</b> program, just type "sqlite" followed by
+the name of an SQLite database.  An SQLite database is really just
+a directory full of GDBM files, so the argument to the sqlite command
+should really be the name of a directory on your disk.  If that
+directory did not previously contain an SQLite database, a new one
+is created for you automatically.  The <b>sqlite</b> program will
+prompt you to enter SQL.  Type in SQL statements (terminated by a
+semicolon, press "Enter" and the SQL will be executed.  It's as
+simple as that!</p>
+
+<p>For example, to create a new SQLite database named "ex1" 
+with a single table named "tbl1", you might do this:</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 {
+$ (((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;)))
+one = hello!
+two = 10
+
+one = goodbye
+two = 20
+sql>
+}
+
+puts {
+<p>(In the example above, and in all subsequent examples, the commands
+you type are shown with a green tint in an italic font and the responses
+from the computer are shown in black with a constant-width font.)</p>
+
+<p>You can terminate the sqlite program by typing your systems
+End-Of-File character (usually a Control-D) or the interrupt
+character (usually a Control-C).</p>
+
+<p>Make sure you type a semicolon at the end of each SQL command.
+The sqlite looks for a semicolon to know when your SQL command is
+complete.  If you omit the semicolon, sqlite will give you a
+continuation prompt and wait for you to enter more text to be
+added to the current SQL command.  This feature allows you to
+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> 
+}
+
+puts {
+<p>If you exit sqlite and look at the contents of the directory "ex1"
+you'll see that it now contains two files: <b>sqlite_master.tcl</b>
+and <b>tbl1.tbl</b>.  The <b>tbl1.tbl</b> file contains all the
+data for table "tbl1" in your database.  The file
+<b>sqlite_master.tbl</b> is a special table found on all SQLite
+databases that records information about all other tables and
+indices.  In general, an SQLite database will contain one "*.tbl"
+file for each table and index in your database, plus the extra
+"sqlite_master.tbl" file used to store the database schema.</p>
+
+<h2>Aside: Querying the SQLITE_MASTER table</h2>
+
+<p>You can execute "SELECT" statements against the
+special sqlite_master table just like any other table
+in an SQLite database.  For example:</p>
+}
+
+Code {
+$ (((sqlite ex1)))
+Enter ".help" for instructions
+sql> (((select * from sqlite_master;)))
+type = table
+name = tbl1
+tbl_name = tbl1
+sql = create table tbl1(one varchar(10), two smallint)
+sql>
+}
+
+puts {
+<p>
+But you cannot execute DROP TABLE, UPDATE, INSERT or DELETE against
+the sqlite_master table.  At least not directly.  The sqlite_master
+table is updated automatically as you create or drop tables and
+indices from the database, but you can not modify sqlite_master
+directly.
+</p>
+
+<h2>Special commands to sqlite</h2>
+
+<p>
+Most of the time, sqlite just reads lines of input and passes them
+on to the SQLite library for execution.
+But if an input line begins with a dot ("."), then
+that line is intercepted and interpreted by the sqlite program itself.
+These "dot commands" are typically used to change the output format
+of queries, or to execute certain command prepackaged query statements.
+</p>
+
+<p>
+For a listing of the available dot commands, you can enter ".help"
+at any time.  For example:
+</p>}
+
+Code {
+sql> (((.help)))
+.exit                  Exit this program
+.explain               Set output mode suitable for EXPLAIN
+.header ON|OFF         Turn display of headers on or off
+.help                  Show this message
+.indices TABLE         Show names of all indices on TABLE
+.mode MODE             Set mode to one of "line", "column", or "list"
+.output FILENAME       Send output to FILENAME
+.output stdout         Send output to the screen
+.schema ?TABLE?        Show the CREATE statements
+.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> 
+}
+
+puts {
+<h2>Changing Output Formats</h2>
+
+<p>The sqlite program is able to show the results of a query
+in three different formats: "line", "column", and "list".  You can
+use the ".mode" dot command to switch between these three output
+formats.</p>
+
+<p>In "line" mode (the default), 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
+separated by a blank line.  Here is an example of line mode
+output:</p>}
+
+Code {
+sql> (((.mode line)))
+sql> (((select * from tbl1;)))
+one = hello
+two = 10
+
+one = goodbye
+two = 20
+sql>
+}
+
+puts {
+<p>In column mode, each record is shown on a separate line with the
+data aligned in columns.  For example:</p>}
+
+Code {
+sql> (((.mode column)))
+sql> (((select * from tbl1;)))
+one         two       
+----------  ----------
+hello       10        
+goodbye     20        
+sql>
+}
+
+puts {
+<p>By default, each column is 10 characters wide. 
+Data that is too wide to fit in a column is trucated.  You can
+adjust the column widths using the ".width" command.  Like this:</p>}
+
+Code {
+sql> (((.width 12 6)))
+sql> (((select * from tbl1;)))
+one           two   
+------------  ------
+hello         10    
+goodbye       20    
+sql>
+}
+
+puts {
+<p>The ".width" command in the example above set the width of the first
+column to 12 and the width of the second column to 6.  All other column
+widths were unaltered.  You can gives as many arguments to ".width" as
+necessary to specify the widths of as many columns as are in your
+query results.</p>
+
+<p>The column labels that appear on the first two lines of output
+can be turned on and off using the ".header" dot command.  In the
+examples above, the column labels are on.  To turn them off you
+could do this:</p>}
+
+Code {
+sql> (((.header off)))
+sql> (((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 symbolc ("|").
+List mode is especially useful when you are going to send the output
+of a query to another program (such as AWK) for additional process.</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>
+}
+
+puts {
+<h2>Writing results to a file</h2>
+
+<p>By default, sqlite sends query results to standard output.  You
+can change this using the ".output" command.  Just put the name of
+an output file as an argument to the .output command and all subsequent
+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
+$ (((cat test_file_1.txt)))
+hello|10
+goodbye|20
+$
+}
+
+puts {
+<h2>Querying the database schema</h2>
+
+<p>The sqlite program provides several convenience commands that
+are useful for looking at the schema of the database.  There is
+nothing that these commands do that cannot be done by some other
+means.  These commands are provided purely as a shortcut.</p>
+
+<p>For example, to see a list of the tables in the database, you
+can enter ".tables".</p>
+}
+
+Code {
+sql> (((.tables)))
+tbl1
+tbl2
+sql>
+}
+
+puts {
+<p>The ".tables" command is the same as setting list mode then
+executing the following query:</p>
+
+<blockquote><pre>
+SELECT name FROM sqlite_master 
+WHERE type='table' 
+ORDER BY name;
+</pre></blockquote>
+
+<p>In fact, if you look at the source code to the sqlite program
+(found in the source tree in the file src/shell.c) you'll find
+exactly the above query.</p>
+
+<p>The ".indices" command works in a similar way to list all of
+the indices for a particular table.  The ".indices" command takes
+a single argument which is the name of the table for which the
+indices are desired.  Last, but not least, is the ".schema" command.
+With no arguments, the ".schema" command shows the original CREATE TABLE
+and CREATE INDEX statements that were used to build the current database.
+If you give the name of a table to ".schema", it shows the original
+CREATE statement used to make that table and all if its indices.
+We have:</p>}
+
+Code {
+sql> (((.schema)))
+create table tbl1(one varchar(10), two smallint)
+CREATE TABLE tbl2 (
+  f1 varchar(30) primary key,
+  f2 text,
+  f3 real
+)
+sql> (((.schema tbl2)))
+CREATE TABLE tbl2 (
+  f1 varchar(30) primary key,
+  f2 text,
+  f3 real
+)
+sql>
+}
+
+puts {
+<p>The ".schema" command accomplishes the same thing as setting
+list mode, then entering the following query:</p>
+
+<blockquote><pre>
+SELECT sql FROM sqlite_master
+ORDER BY tbl_name, type DESC, name
+</pre></blockquote>
+
+<h2>Other Dot Commands</h2>
+
+<p>The ".explain" dot command can be used to set the output mode
+to "column" and to set the column widths to values that are reasonable
+for looking at the output of an EXPLAIN command.  The EXPLAIN command
+is an SQLite-specific command that is useful for debugging.  If any
+regular SQL is prefaced by EXPLAIN, then the SQL command is parsed and
+analyized but is not executed.  Instead, the sequence of virtual machine
+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;)))
+addr  opcode        p1     p2     p3          
+----  ------------  -----  -----  -------------------------------------   
+0     ListOpen      0      0                  
+1     Open          0      0      tbl1        
+2     Next          0      9                  
+3     Field         0      1                  
+4     Integer       20     0                  
+5     Ge            0      2                  
+6     Key           0      0                  
+7     ListWrite     0      0                  
+8     Goto          0      2                  
+9     Noop          0      0                  
+10    ListRewind    0      0                  
+11    ListRead      0      14                 
+12    Delete        0      0                  
+13    Goto          0      11                 
+14    ListClose     0      0                  
+}
+
+puts {
+<p>And finally, we mention the ".exit" command which causes the
+sqlite program to exit.</p>
+
+<h2>Using sqlite in a shell script</h2>
+
+<p>
+One way to use sqlite in a shell script is to use "echo" or
+"cat" to generate a sequence of commands in a file, then invoke sqlite 
+while redirecting input from the generated command file.  This
+works fine and is appropriate in many circumstances.  But as
+an added convenience, sqlite allows a single SQL command to be
+entered on the command line as a second argument after the
+database name.  When the sqlite program is launched with two
+arguments, the second argument is passed to the SQLite library
+for processing, the query results are printed on standard output
+in list mode, and the program exits.  This mechanism is designed
+to make sqlite easy to use in conjunction with programs like
+"awk".  For example:</p>}
+
+Code {
+$ (((sqlite ex1 'select * from tbl1' |)))
+> ((( awk '{printf "<tr><td>%s<td>%s\n",$1,$2 }')))
+<tr><td>hello<td>10
+<tr><td>goodbye<td>20
+$
+}
+
+puts {
+<h2>Compiling the sqlite program from sources</h2>
+
+<p>
+The sqlite program is built automatically when you compile the
+sqlite library.  Just get a copy of the source tree, run
+"configure" and then "make".</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>}