:-) (CVS 125)
FossilOrigin-Name: ab9c533a3a256ca9d59a6a580c6064c903d962a5
This commit is contained in:
parent
60bfa67829
commit
bec3f4022f
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
||||
C spelling\serror\s(CVS\s124)
|
||||
D 2000-08-03T15:13:30
|
||||
C :-)\s(CVS\s125)
|
||||
D 2000-08-04T13:49:02
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in 670aa9413cb2cdcded23b328a9e255c845c41a1e
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
@ -18,7 +18,7 @@ F src/select.c d382e96c2221d08367cc87976f2b574537c9de97
|
||||
F src/shell.c 2fd370838742afa068cfcdd05b667ff89bab25b6
|
||||
F src/sqlite.h 82ae53028e27919250f886ff9d7c4927de81978a
|
||||
F src/sqliteInt.h f6d1e139b3bfa4ceff2136684e19d76b53178ec0
|
||||
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
||||
F src/tclsqlite.c 6ced80832c13e70dae5a176da2dff3d5f4801d92
|
||||
F src/tokenize.c 77ff8164a8751994bc9926ce282847f653ac0c16
|
||||
F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
|
||||
F src/util.c b75b33e6bd5d47898bb7ed9fdd0dea4fe7c19b00
|
||||
@ -61,14 +61,14 @@ F www/arch.tcl 4f6a9afecc099a27bba17b4f8cc9561abc15dc40
|
||||
F www/c_interface.tcl 29593cf77025bab137b7ba64b9459eb5eb6b4873
|
||||
F www/changes.tcl 4a1aaaaad9a9b4cf3259264955c225b98a9d025d
|
||||
F www/crosscompile.tcl 19734ce7f18b16ff2ed8479412abf8aca56e1dcc
|
||||
F www/fileformat.tcl 1c353d202cc75de55a916a1bab80e7b3cc5660ee
|
||||
F www/index.tcl 2ea89f6f90d4d4efd591b9679f0e71a9a4adc2f5
|
||||
F www/lang.tcl 1645e9107d75709be4c6099b643db235bbe0a151
|
||||
F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9
|
||||
F www/index.tcl 421bcabc6839eb00698b75b169caa8a559454515
|
||||
F www/lang.tcl 9192e114b19987e630a41e879585b87006eb84a1
|
||||
F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
|
||||
F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/sqlite.tcl 69781eaffb02e17aa4af28b76a2bedb19baa8e9f
|
||||
F www/sqlite.tcl 7c2ee68063fa59463f55d5bac1ffe3e50d8a817f
|
||||
F www/vdbe.tcl bcbfc33bcdd0ebad95eab31286adb9e1bc289520
|
||||
P 4dabf5e4e647f6dcdcfd45d1e885e379357a2d57
|
||||
R 32c359deccb869c0c62b7f96f90c83a2
|
||||
P 577421e5d370e220b5f228f4c711d49ce95612dc
|
||||
R 2cf2ed69cb63137ea0c1416ab3f1b043
|
||||
U drh
|
||||
Z e70ff0d215fda57f6188c3a588c372be
|
||||
Z 70478f10c211823f0de6f883859c4135
|
||||
|
@ -1 +1 @@
|
||||
577421e5d370e220b5f228f4c711d49ce95612dc
|
||||
ab9c533a3a256ca9d59a6a580c6064c903d962a5
|
120
src/tclsqlite.c
120
src/tclsqlite.c
@ -23,13 +23,24 @@
|
||||
*************************************************************************
|
||||
** A TCL Interface to SQLite
|
||||
**
|
||||
** $Id: tclsqlite.c,v 1.5 2000/06/04 12:58:38 drh Exp $
|
||||
** $Id: tclsqlite.c,v 1.6 2000/08/04 13:49:02 drh Exp $
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include <tcl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** There is one instance of this structure for each SQLite database
|
||||
** that has been opened by the SQLite TCL interface.
|
||||
*/
|
||||
typedef struct SqliteDb SqliteDb;
|
||||
struct SqliteDb {
|
||||
sqlite *db; /* The "real" database structure */
|
||||
Tcl_Interp *interp; /* The interpreter used for this database */
|
||||
char *zBusy; /* The name of the busy callback routine */
|
||||
};
|
||||
|
||||
/*
|
||||
** An instance of this structure passes information thru the sqlite
|
||||
** logic from the original TCL command into the callback routine.
|
||||
@ -81,7 +92,38 @@ static int DbEvalCallback(
|
||||
** Called when the command is deleted.
|
||||
*/
|
||||
static void DbDeleteCmd(void *db){
|
||||
sqlite_close((sqlite*)db);
|
||||
SqliteDb *pDb = (SqliteDb*)db;
|
||||
sqlite_close(pDb->db);
|
||||
if( pDb->zBusy ){
|
||||
Tcl_Free(pDb->zBusy);
|
||||
}
|
||||
Tcl_Free((char*)pDb);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called when a database file is locked while trying
|
||||
** to execute SQL.
|
||||
*/
|
||||
static int DbBusyHandler(void *cd, const char *zTable, int nTries){
|
||||
SqliteDb *pDb = (SqliteDb*)cd;
|
||||
int rc;
|
||||
char zVal[30];
|
||||
char *zCmd;
|
||||
char *zResult;
|
||||
Tcl_DString cmd;
|
||||
|
||||
Tcl_DStringInit(&cmd);
|
||||
Tcl_DStringAppend(&cmd, pDb->zBusy, -1);
|
||||
Tcl_DStringAppendElement(&cmd, zTable);
|
||||
sprintf(zVal, " %d", nTries);
|
||||
Tcl_DStringAppend(&cmd, zVal, -1);
|
||||
zCmd = Tcl_DStringValue(&cmd);
|
||||
rc = Tcl_Eval(pDb->interp, zCmd);
|
||||
Tcl_DStringFree(&cmd);
|
||||
if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -100,7 +142,7 @@ static void DbDeleteCmd(void *db){
|
||||
static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
char *z;
|
||||
int n, c;
|
||||
sqlite *db = cd;
|
||||
SqliteDb *pDb = (SqliteDb*)cd;
|
||||
if( argc<2 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
" SUBCOMMAND ...\"", 0);
|
||||
@ -110,6 +152,38 @@ static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
n = strlen(z);
|
||||
c = z[0];
|
||||
|
||||
/* $db busy ?CALLBACK?
|
||||
**
|
||||
** Invoke the given callback if an SQL statement attempts to open
|
||||
** a locked database file.
|
||||
*/
|
||||
if( c=='b' && strncmp(z,"busy",n)==0 ){
|
||||
if( argc>3 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"",
|
||||
argv[0], " busy ?CALLBACK?", 0);
|
||||
return TCL_ERROR;
|
||||
}else if( argc==2 ){
|
||||
if( pDb->zBusy ){
|
||||
Tcl_AppendResult(interp, pDb->zBusy, 0);
|
||||
}
|
||||
}else{
|
||||
if( pDb->zBusy ){
|
||||
Tcl_Free(pDb->zBusy);
|
||||
pDb->zBusy = 0;
|
||||
}
|
||||
if( argv[2][0] ){
|
||||
pDb->zBusy = Tcl_Alloc( strlen(argv[2]) + 1 );
|
||||
if( pDb->zBusy ){
|
||||
strcpy(pDb->zBusy, argv[2]);
|
||||
}
|
||||
}
|
||||
if( pDb->zBusy ){
|
||||
pDb->interp = interp;
|
||||
sqlite_busy_handler(pDb->db, DbBusyHandler, pDb);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
/* $db close
|
||||
**
|
||||
** Shutdown the database
|
||||
@ -139,7 +213,7 @@ static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
** $db eval $sql ?array { ...code... }?
|
||||
**
|
||||
** The SQL statement in $sql is evaluated. For each row, the values are
|
||||
** placed in elements of the array named "array" and ...code.. is executed.
|
||||
** placed in elements of the array named "array" and ...code... is executed.
|
||||
** If "array" and "code" are omitted, then no callback is every invoked.
|
||||
** If "array" is an empty string, then the values are placed in variables
|
||||
** that have the same name as the fields extracted by the query.
|
||||
@ -154,26 +228,43 @@ static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
" eval SQL ?ARRAY-NAME CODE?", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pDb->interp = interp;
|
||||
if( argc==5 ){
|
||||
cbData.interp = interp;
|
||||
cbData.once = 1;
|
||||
cbData.zArray = argv[3];
|
||||
cbData.zCode = argv[4];
|
||||
zErrMsg = 0;
|
||||
rc = sqlite_exec(db, argv[2], DbEvalCallback, &cbData, &zErrMsg);
|
||||
rc = sqlite_exec(pDb->db, argv[2], DbEvalCallback, &cbData, &zErrMsg);
|
||||
}else{
|
||||
rc = sqlite_exec(db, argv[2], 0, 0, &zErrMsg);
|
||||
rc = sqlite_exec(pDb->db, argv[2], 0, 0, &zErrMsg);
|
||||
}
|
||||
if( zErrMsg ){
|
||||
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
|
||||
free(zErrMsg);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** $db timeout MILLESECONDS
|
||||
**
|
||||
** Delay for the number of milliseconds specified when a file is locked.
|
||||
*/
|
||||
if( c=='t' && strncmp(z,"timeout",n)==0 ){
|
||||
int ms;
|
||||
if( argc!=3 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
" timeout MILLISECONDS", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR;
|
||||
sqlite_busy_timeout(pDb->db, ms);
|
||||
}else
|
||||
|
||||
/* The default
|
||||
*/
|
||||
else{
|
||||
{
|
||||
Tcl_AppendResult(interp,"unknown subcommand \"", z,
|
||||
"\" - should be one of: close complete eval", 0);
|
||||
return TCL_ERROR;
|
||||
@ -197,7 +288,7 @@ static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
*/
|
||||
static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
int mode;
|
||||
sqlite *p;
|
||||
SqliteDb *p;
|
||||
char *zErrMsg;
|
||||
if( argc!=3 && argc!=4 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
@ -210,13 +301,20 @@ static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zErrMsg = 0;
|
||||
p = sqlite_open(argv[2], mode, &zErrMsg);
|
||||
p = Tcl_Alloc( sizeof(*p) );
|
||||
if( p==0 ){
|
||||
Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->db = sqlite_open(argv[2], mode, &zErrMsg);
|
||||
if( p->db==0 ){
|
||||
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
|
||||
Tcl_Free((char*)p);
|
||||
free(zErrMsg);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_CreateCommand(interp, argv[1], DbCmd, p, DbDeleteCmd);
|
||||
Tcl_CreateCommand(interp, argv[1], DbCmd, (char*)p, DbDeleteCmd);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the fileformat.html file.
|
||||
#
|
||||
set rcsid {$Id: fileformat.tcl,v 1.3 2000/08/02 12:26:30 drh Exp $}
|
||||
set rcsid {$Id: fileformat.tcl,v 1.4 2000/08/04 13:49:03 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -215,8 +215,7 @@ table that has the corresponding value for the <b>a</b> column.</p>
|
||||
The index entry for -11 contains only a single entry and is 4
|
||||
bytes in size. The index entry for 10 is 16 bytes in size but
|
||||
contains only 2 entries. The first integer is the number of
|
||||
entires. The two integer keys follow. The last 4 bytes unused
|
||||
and are set to zero.
|
||||
entires. The two integer keys follow. The last 4 bytes are unused.
|
||||
}
|
||||
|
||||
puts {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this TCL script to generate HTML for the index.html file.
|
||||
#
|
||||
set rcsid {$Id: index.tcl,v 1.25 2000/08/03 15:13:30 drh Exp $}
|
||||
set rcsid {$Id: index.tcl,v 1.26 2000/08/04 13:49:03 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head><title>SQLite: An SQL Database Engine Built Atop GDBM</title></head>
|
||||
@ -132,7 +132,7 @@ 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>
|
||||
|
||||
<p>To build sqlite, just unwrap the tarball, create a separate
|
||||
<p>To build sqlite under Unix, just unwrap the tarball, create a separate
|
||||
build directory, run configure from the build directory and then
|
||||
type "make". For example:</p>
|
||||
|
||||
@ -144,6 +144,9 @@ $ ../sqlite/configure
|
||||
$ make <i> Builds "sqlite" and "libsqlite.a" </i>
|
||||
$ make test <i> Optional: run regression tests </i>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>Instructions for building SQLite for WindowsNT are
|
||||
found <a href="crosscompile.html">here</a>.
|
||||
}
|
||||
|
||||
puts {<h2>Command-line Usage Example</h2>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.4 2000/06/09 14:14:34 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.5 2000/08/04 13:49:03 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -139,7 +139,7 @@ ON <table-name> ( <column-name> [, <column-name>]* )
|
||||
|
||||
puts {
|
||||
<p>The CREATE INDEX command consists of the keywords "CREATE INDEX" followed
|
||||
by the name of the new index, the keyword "ON" the name of a previously
|
||||
by the name of the new index, the keyword "ON", the name of a previously
|
||||
created table that is to be indexed, and a parenthesized list of names of
|
||||
columns in the table that are used for the index key.
|
||||
Each column name can be followed by one of the "ASC" or "DESC" keywords
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: sqlite.tcl,v 1.11 2000/07/28 14:32:51 drh Exp $}
|
||||
set rcsid {$Id: sqlite.tcl,v 1.12 2000/08/04 13:49:03 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -28,8 +28,9 @@ 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
|
||||
is created for you automatically. If the directory did not previously
|
||||
exist, it is automatically created. The <b>sqlite</b> program will
|
||||
then 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>
|
||||
|
||||
@ -49,7 +50,6 @@ proc Code {body} {
|
||||
}
|
||||
|
||||
Code {
|
||||
$ (((mkdir ex1)))
|
||||
$ (((sqlite ex1)))
|
||||
Enter ".help" for instructions
|
||||
sqlite> (((create table tbl1(one varchar(10), two smallint);)))
|
||||
@ -230,7 +230,7 @@ sqlite>
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>By default, each column is 10 characters wide.
|
||||
<p>By default, each column is at least 10 characters wide.
|
||||
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>}
|
||||
|
||||
@ -251,6 +251,13 @@ 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>If you specify a column a width of 0, then the column
|
||||
width is automatically adjusted to be the maximum of three
|
||||
numbers: 10, the width of the header, and the width of the
|
||||
first row of data. This makes the column width self-adjusting.
|
||||
The default width setting for every column is this
|
||||
auto-adjusting 0 value.</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
|
||||
@ -270,6 +277,19 @@ is formatted to look like SQL INSERT statements. You can use insert
|
||||
mode to generate text that can later be used to input data into a
|
||||
different database.</p>
|
||||
|
||||
<p>When specifying insert mode, you have to give an extra argument
|
||||
which is the name of the table to be inserted into. For example:</p>
|
||||
}
|
||||
|
||||
Code {
|
||||
sqlite> (((.mode insert new_table)))
|
||||
sqlite> (((select * from tbl1;)))
|
||||
INSERT INTO 'new_table' VALUES('hello',10);
|
||||
INSERT INTO 'new_table' VALUES('goodbye',20);
|
||||
sqlite>
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>The last output mode is "html". In this mode, sqlite writes
|
||||
the results of the query as an XHTML table. The beginning
|
||||
<TABLE> and the ending </TABLE> are not written, but
|
||||
@ -365,6 +385,7 @@ list mode, then entering the following query:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
SELECT sql FROM sqlite_master
|
||||
WHERE type!='meta'
|
||||
ORDER BY tbl_name, type DESC, name
|
||||
</pre></blockquote>
|
||||
|
||||
@ -373,7 +394,7 @@ want the schema for a single table, the query looks like this:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
SELECT sql FROM sqlite_master
|
||||
WHERE tbl_name LIKE '%s'
|
||||
WHERE tbl_name LIKE '%s' AND type!='meta'
|
||||
ORDER BY type DESC, name
|
||||
</pre></blockquote>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user