2.0-Alpha-2 release (CVS 258)
FossilOrigin-Name: d2a1aac46782c0d3852e34a3b32a6b2ccd93a256
This commit is contained in:
parent
474d3d6156
commit
254cba2429
@ -226,6 +226,7 @@ sqlite.tar.gz:
|
||||
pwd=`pwd`; cd $(TOP)/..; tar czf $$pwd/sqlite.tar.gz sqlite
|
||||
|
||||
index.html: $(TOP)/www/index.tcl sqlite.tar.gz last_change
|
||||
cp ../sqlite-*.tar.gz .
|
||||
tclsh $(TOP)/www/index.tcl `cat $(TOP)/VERSION` >index.html
|
||||
|
||||
sqlite.html: $(TOP)/www/sqlite.tcl
|
||||
@ -237,9 +238,6 @@ 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
|
||||
|
||||
lang.html: $(TOP)/www/lang.tcl
|
||||
tclsh $(TOP)/www/lang.tcl >lang.html
|
||||
|
||||
@ -272,7 +270,6 @@ PUBLISH = \
|
||||
index.html \
|
||||
sqlite.html \
|
||||
changes.html \
|
||||
fileformat.html \
|
||||
lang.html \
|
||||
opcode.html \
|
||||
arch.html \
|
||||
@ -286,8 +283,8 @@ PUBLISH = \
|
||||
website: $(PUBLISH)
|
||||
|
||||
publish: $(PUBLISH)
|
||||
chmod 0644 $(PUBLISH)
|
||||
scp $(PUBLISH) hwaci@oak.he.net:public_html/sw/sqlite
|
||||
chmod 0644 $(PUBLISH) sqlite-*.tar.gz
|
||||
scp $(PUBLISH) sqlite-*.tar.gz hwaci@oak.he.net:public_html/sw/sqlite
|
||||
|
||||
install: sqlite libsqlite.a sqlite.h
|
||||
mv sqlite /usr/bin
|
||||
|
43
manifest
43
manifest
@ -1,8 +1,8 @@
|
||||
C Add\sthe\sOpenReadOnly()\sOS\smethod\sto\sfix\sa\sbug\sin\sthe\spager.\s(CVS\s257)
|
||||
D 2001-09-19T13:58:44
|
||||
F Makefile.in 1d9592c4aeedd3643b2e1dfa037ce5faf54805a3
|
||||
C 2.0-Alpha-2\srelease\s(CVS\s258)
|
||||
D 2001-09-20T01:44:43
|
||||
F Makefile.in 0af884b48d7dbcd01d73a9d93cb3e19b34c9f087
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
F VERSION 3861a21803fcd9eb92a403027b0da2bb7add4de1
|
||||
F VERSION 6942aa44940d2972bd72f671a631060106e77f7e
|
||||
F configure aad857a97ca28a584228869186eb4cd7dbebbb3a x
|
||||
F configure.in 0000c0d62beb47cae1d2d81a197c7fe6efd56a45
|
||||
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||
@ -16,9 +16,9 @@ F src/expr.c 343a515a4abaf60e9e26c7412aa8c43fd3eae97d
|
||||
F src/insert.c b34860ea58525754f18bde652f74161295ca2455
|
||||
F src/main.c 5e5794eea3316dd3a63c112ccdcc997b9118f345
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/os.c 43735db052288f8bfee56e09dfa293c202ff93a3
|
||||
F src/os.h 6d627d8629a204c474cf13aa098654658378a81f
|
||||
F src/pager.c a77c7fd3f33c0c6834a042b9b0d4a8128553532e
|
||||
F src/os.c faf9f484f3261c7650021cae79294338491f2cfb
|
||||
F src/os.h 0f478e2fef5ec1612f94b59b163d4807d4c77d6d
|
||||
F src/pager.c 0fe02b63a89d8eebb42ad30529d0c7cc918ecb94
|
||||
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||
F src/parse.y 2bcf47bb8e6afd8bc10aebd555fa07b73905bee4
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
@ -26,7 +26,7 @@ F src/random.c b6a57e85288470b013ad584a8813e893b60e62fe
|
||||
F src/select.c 7d90a6464906419fde96c0707a4cf4f3280db318
|
||||
F src/shell.c 8e573138074e0b9526fca59b3eac22bdf18ecc03
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in 689401a6cfb4c2344e67d80fa6bb0d74c87e6e31
|
||||
F src/sqlite.h.in 5d78c86bd9a9b8bbba65f860fbaf71c1882d6030
|
||||
F src/sqliteInt.h 667126497697d58a114d9db492f38c99eadb36d7
|
||||
F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac
|
||||
F src/tclsqlite.c 04a35d04f06046acc3944121dc6c36717f7f36d5
|
||||
@ -55,7 +55,7 @@ F test/main.test 085ece17913a487caacbc0a392638c958c83a75d
|
||||
F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740
|
||||
F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
|
||||
F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
|
||||
F test/printf.test 93ecd43cc48e863a325560f36c3b2741f5fe0308
|
||||
F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
|
||||
F test/quick.test b6ec50f808efc06595fd324bf4f3fabadb9c7e9c
|
||||
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
|
||||
F test/rowid.test 427bfbbe9684fe7a2f851aa05badaae6d4972ce8
|
||||
@ -69,7 +69,7 @@ F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
||||
F test/table.test 52fdca1632580fb638c7b7dd14f4d37ecc09f994
|
||||
F test/tableapi.test 162840153191a91a7dce6395f2334f9aef713b37
|
||||
F test/tclsqlite.test a57bb478d7e9f0b2c927f92e161f391e2896631a
|
||||
F test/tester.tcl 4d93d04bb43c5936f33d30df82d2801b519df74e
|
||||
F test/tester.tcl 957cd92fe8645b829da175d94b7ddb7ea68dac39
|
||||
F test/trans.test 997c8dcc15c479bc2cedc42220cf2d265e63d2a8
|
||||
F test/update.test b320ea22899e80b32b4d21c54591eb7a6ba4d6bd
|
||||
F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
|
||||
@ -81,22 +81,21 @@ F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
||||
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
|
||||
F www/arch.fig 468adec4c4d7ef70fdc0a9e74e3afc86f440a40f
|
||||
F www/arch.png ce828ead98b46684937972aac17cd6569a2feb20
|
||||
F www/arch.tcl f5d76cea4feb997c3a474191cbe4fa52c8847ad6
|
||||
F www/c_interface.tcl ddca19005c47dd5a15882addc02fff5de83d8ed9
|
||||
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||
F www/arch.tcl c1891efdc00cd76eec72bdbf8b446195902932a3
|
||||
F www/c_interface.tcl 52ae81c89bf906b358e04857bd3f76b1a7f61c1b
|
||||
F www/changes.tcl 0a791dbf5af35d7adde6fcce8465829d599f000e
|
||||
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||
F www/fileformat.tcl cfb7fba80b7275555281ba2f256c00734bcdd1c9
|
||||
F www/index.tcl a9c1bfea2e854856d9cb83a0cf850d657cd92588
|
||||
F www/lang.tcl 0969ba9f13b3555e54ccdb8ec462dee2de0bf223
|
||||
F www/index.tcl 13829cd0338bc12ccc50fbcdec17d77dab6d35e0
|
||||
F www/lang.tcl d093693db5d4d7b7127d134807e4e65dea0e5dee
|
||||
F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
|
||||
F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/opcode.tcl 60222aeb57a7855b2582c374b8753cb5bb53c4ab
|
||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P abff526d005b3b46904de091753cc79548739ad8
|
||||
R 4864863de07f710a3f6b561c261f5e5d
|
||||
P 82db5456c9817283d725daf4e1081d32a71466ad
|
||||
R da13c8d8c124b473a3b231a811f4208c
|
||||
U drh
|
||||
Z e4c492c8b9528b70a7181a2203d31493
|
||||
Z 116b290f301c5913c5ae5b5e56236636
|
||||
|
@ -1 +1 @@
|
||||
82db5456c9817283d725daf4e1081d32a71466ad
|
||||
d2a1aac46782c0d3852e34a3b32a6b2ccd93a256
|
13
src/os.c
13
src/os.c
@ -59,7 +59,7 @@ int sqliteOsFileExists(const char *zFilename){
|
||||
#endif
|
||||
#if OS_WIN
|
||||
HANDLE h;
|
||||
h = CreateFile(zBuf,
|
||||
h = CreateFile(zFilename,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
@ -67,7 +67,7 @@ int sqliteOsFileExists(const char *zFilename){
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h!=INVALID_FILE_HANDLE ){
|
||||
if( h!=INVALID_HANDLE_VALUE ){
|
||||
CloseHandle(h);
|
||||
return 1;
|
||||
}
|
||||
@ -253,8 +253,11 @@ int sqliteOsTempFileName(char *zBuf){
|
||||
}while( access(zBuf,0)==0 );
|
||||
#endif
|
||||
#if OS_WIN
|
||||
static char zChars[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
int i, j;
|
||||
HANDLE h;
|
||||
char zTempPath[SQLITE_TEMPNAME_SIZE];
|
||||
GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
|
||||
for(;;){
|
||||
@ -297,7 +300,7 @@ int sqliteOsRead(OsFile id, void *pBuf, int amt){
|
||||
return got==amt ? SQLITE_OK : SQLITE_IOERR;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
int got;
|
||||
DWORD got;
|
||||
if( !ReadFile(id, pBuf, amt, &got, 0) ){
|
||||
got = 0;
|
||||
}
|
||||
@ -317,7 +320,7 @@ int sqliteOsWrite(OsFile id, const void *pBuf, int amt){
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
int wrote;
|
||||
DWORD wrote;
|
||||
if( !WriteFile(id, pBuf, amt, &wrote, 0) || wrote<amt ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
|
4
src/os.h
4
src/os.h
@ -31,9 +31,11 @@
|
||||
#endif
|
||||
|
||||
#if OS_WIN
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
typedef HANDLE OsFile;
|
||||
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
||||
# deifne SQLITE_MIN_SLEEP_MS 1
|
||||
# define SQLITE_MIN_SLEEP_MS 1
|
||||
#endif
|
||||
|
||||
int sqliteOsDelete(const char*);
|
||||
|
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.23 2001/09/19 13:58:44 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.24 2001/09/20 01:44:43 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@ -327,7 +327,7 @@ static int pager_playback(Pager *pPager){
|
||||
*/
|
||||
for(i=nRec-1; i>=0; i--){
|
||||
/* Seek to the beginning of the segment */
|
||||
off_t ofst;
|
||||
int ofst;
|
||||
ofst = i*sizeof(PageRecord) + sizeof(aMagic) + sizeof(Pgno);
|
||||
rc = sqliteOsSeek(pPager->jfd, ofst);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.17 2001/09/16 00:13:27 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.18 2001/09/20 01:44:43 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_H_
|
||||
#define _SQLITE_H_
|
||||
@ -144,11 +144,11 @@ int sqlite_exec(
|
||||
#define SQLITE_INTERRUPT 8 /* Operation terminated by sqlite_interrupt() */
|
||||
#define SQLITE_IOERR 9 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 10 /* The database disk image is malformed */
|
||||
#define SQLITE_NOTFOUND 11 /* Table or record not found */
|
||||
#define SQLITE_NOTFOUND 11 /* (Internal Only) Table or record not found */
|
||||
#define SQLITE_FULL 12 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 13 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 14 /* Database lock protocol error */
|
||||
#define SQLITE_EMPTY 15 /* Database table is empty */
|
||||
#define SQLITE_EMPTY 15 /* (Internal Only) Database table is empty */
|
||||
#define SQLITE_SCHEMA 16 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 17 /* Too much data for one row of a table */
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the sqlite_*_printf() interface.
|
||||
#
|
||||
# $Id: printf.test,v 1.3 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: printf.test,v 1.4 2001/09/20 01:44:43 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -39,6 +39,9 @@ foreach v {1 2 5 10 99 100 1000000 999999999 0 -1 -2 -5 -10 -99 -100 -9999999} {
|
||||
incr n
|
||||
}
|
||||
|
||||
|
||||
if {$::tcl_platform(platform)!="windows"} {
|
||||
|
||||
set m 1
|
||||
foreach {a b} {1 1 5 5 10 10 10 5} {
|
||||
set n 1
|
||||
@ -63,6 +66,8 @@ foreach {a b} {1 1 5 5 10 10 10 5} {
|
||||
incr m
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do_test printf-3.1 {
|
||||
sqlite_mprintf_str {A String: (%*.*s)} 10 10 {This is the string}
|
||||
} [format {A String: (%*.*s)} 10 10 {This is the string}]
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements some common TCL routines used for regression
|
||||
# testing the SQLite library
|
||||
#
|
||||
# $Id: tester.tcl,v 1.18 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: tester.tcl,v 1.19 2001/09/20 01:44:43 drh Exp $
|
||||
|
||||
# Make sure tclsqlite was compiled correctly. Abort now with an
|
||||
# error message if not.
|
||||
@ -42,8 +42,9 @@ if {[sqlite -tcl-uses-utf]} {
|
||||
|
||||
# Create a test database
|
||||
#
|
||||
file delete -force ./test.db
|
||||
file delete -force ./test.db-journal
|
||||
catch {db close}
|
||||
file delete -force test.db
|
||||
file delete -force test.db-journal
|
||||
sqlite db ./test.db
|
||||
|
||||
# Abort early if this script has been run before.
|
||||
|
33
www/arch.fig
33
www/arch.fig
@ -7,38 +7,43 @@ Letter
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 450 4875 450 4875 1275 2550 1275 2550 450
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 8550 3675 9075
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 9075 4875 9075 4875 9900 2550 9900 2550 9075
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 7200 3675 7725
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 7725 4875 7725 4875 8550 2550 8550 2550 7725
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 5775 3675 6300
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 6300 4875 6300 4875 7200 2550 7200 2550 6300
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 4500 4875 4500 4875 5775 2550 5775 2550 4500
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 3975 3675 4500
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 2625 3675 3150
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 3150 4875 3150 4875 3975 2550 3975 2550 3150
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 1275 3675 1800
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 9900 3675 10425
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 10425 4875 10425 4875 11250 2550 11250 2550 10425
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 9075 4875 9075 4875 9900 2550 9900 2550 9075
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 7725 4875 7725 4875 8550 2550 8550 2550 7725
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 6300 4875 6300 4875 7200 2550 7200 2550 6300
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 4500 4875 4500 4875 5775 2550 5775 2550 4500
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 3150 4875 3150 4875 3975 2550 3975 2550 3150
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 1800 4875 1800 4875 2625 2550 2625 2550 1800
|
||||
2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
|
||||
2550 450 4875 450 4875 1275 2550 1275 2550 450
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1020 3675 750 Interface\001
|
||||
4 1 0 100 0 0 14 0.0000 4 195 2040 3675 1125 main.c table.c tclsqlite.c\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1920 3675 6675 Virtual Machine\001
|
||||
@ -55,3 +60,5 @@ Single
|
||||
4 1 0 100 0 0 14 0.0000 4 150 600 3675 8400 btree.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 645 3675 9750 pager.c\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1620 3675 8025 B-tree Driver\001
|
||||
4 1 0 100 0 0 14 0.0000 4 105 345 3675 11100 os.c\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1470 3675 10725 OS Interface\001
|
||||
|
BIN
www/arch.png
BIN
www/arch.png
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 4.3 KiB |
48
www/arch.tcl
48
www/arch.tcl
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: arch.tcl,v 1.4 2001/09/16 00:13:29 drh Exp $}
|
||||
set rcsid {$Id: arch.tcl,v 1.5 2001/09/20 01:44:43 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -22,7 +22,12 @@ puts {
|
||||
<tr><th>Block Diagram Of SQLite</th></tr>
|
||||
<tr><td><img src="arch.png"></td></tr>
|
||||
</table>
|
||||
<p>This file describes the architecture of the SQLite library.
|
||||
<p>This document describes the architecture of the SQLite library.
|
||||
The information here is useful to those who want to understand or
|
||||
modify the inner workings of SQLite.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A block diagram showing the main components of SQLite
|
||||
and how they interrelate is shown at the right. The text that
|
||||
follows will provide a quick overview of each of these components.
|
||||
@ -39,9 +44,8 @@ information on the C interface to SQLite is
|
||||
|
||||
<p>To avoid name collisions with other software, all external
|
||||
symbols in the SQLite library begin with the prefix <b>sqlite</b>.
|
||||
Those symbols that are intended for external use (as oppose to
|
||||
those which are for internal use only but which have to be exported
|
||||
do to limitations of the C linker's scoping mechanism) begin
|
||||
Those symbols that are intended for external use (in other words,
|
||||
those symbols which form the API for SQLite) begin
|
||||
with <b>sqlite_</b>.</p>
|
||||
|
||||
<h2>Tokenizer</h2>
|
||||
@ -50,13 +54,14 @@ with <b>sqlite_</b>.</p>
|
||||
interface passes that string to the tokenizer. The job of the tokenizer
|
||||
is to break the original string up into tokens and pass those tokens
|
||||
one by one to the parser. The tokenizer is hand-coded in C.
|
||||
(There is no "lex" code here.) All of the code for the tokenizer
|
||||
All of the code for the tokenizer
|
||||
is contained in the <b>tokenize.c</b> source file.</p>
|
||||
|
||||
<p>Note that in this design, the tokenizer calls the parser. People
|
||||
who are familiar with YACC and BISON may be used to doing things the
|
||||
other way around -- having the parser call the tokenizer. This author
|
||||
as done it both ways, and finds things generally work out nicer for
|
||||
other way around -- having the parser call the tokenizer. The author
|
||||
of SQLite
|
||||
has done it both ways and finds things generally work out nicer for
|
||||
the tokenizer to call the parser. YACC has it backwards.</p>
|
||||
|
||||
<h2>Parser</h2>
|
||||
@ -122,14 +127,39 @@ is stored with the key in an area called "payload". Up to 236 bytes of
|
||||
payload can be stored with each B-tree entry. Any additional payload
|
||||
is stored in a chain of overflow pages.</p>
|
||||
|
||||
<p>The interface to the B-tree subsystem is defined by the header file
|
||||
<b>btree.h</b>.
|
||||
</p>
|
||||
|
||||
<h2>Page Cache</h2>
|
||||
|
||||
<p>The page cache provides the rollback and atomic commit abstraction
|
||||
<p>The B-tree module requests information from the disk in 1024 byte
|
||||
chunks. The page cache is reponsible for reading, writing, and
|
||||
caching these chunks for the B-tree module.
|
||||
The page cache also provides the rollback and atomic commit abstraction
|
||||
and takes care of reader/writer locking of the database file. The
|
||||
B-tree driver requests particular pages from the page cache and notifies
|
||||
the page cache when it wants to modify pages and commit or rollback its
|
||||
changes and the page cache handles all the messy details of making sure
|
||||
the requests are handled quickly, safely, and efficiently.</p>
|
||||
|
||||
<p>The code to implement the page cache is contained in the single C
|
||||
source file <b>pager.c</b>. The interface to the page cache subsystem
|
||||
is defined by the header file <b>pager.h</b>.
|
||||
</p>
|
||||
|
||||
<h2>OS Interface</h2>
|
||||
|
||||
<p>
|
||||
In order to provide portability between POSIX and Win32 operating systems,
|
||||
SQLite uses an abstraction layer to interace with the operating system.
|
||||
The <b>os.c</b> file contains about 20 routines used for opening and
|
||||
closing files, deleting files, creating and deleting locks on files,
|
||||
flushing the disk cache, and so forth. Each of these functions contains
|
||||
two implementations separated by #ifdefs: one for POSIX and the other
|
||||
for Win32. The interface to the OS abstraction layer is defined by
|
||||
the <b>os.h</b> header file.
|
||||
</p>
|
||||
}
|
||||
|
||||
puts {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: c_interface.tcl,v 1.14 2001/04/05 16:25:53 drh Exp $}
|
||||
set rcsid {$Id: c_interface.tcl,v 1.15 2001/09/20 01:44:43 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -42,13 +42,21 @@ int sqlite_exec(
|
||||
);
|
||||
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
#define SQLITE_INTERNAL 1 /* An internal logic error in SQLite */
|
||||
#define SQLITE_ERROR 2 /* SQL error or missing database */
|
||||
#define SQLITE_ERROR 1 /* SQL error or missing database */
|
||||
#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */
|
||||
#define SQLITE_PERM 3 /* Access permission denied */
|
||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
||||
#define SQLITE_BUSY 5 /* One or more database files are locked */
|
||||
#define SQLITE_NOMEM 6 /* A malloc() failed */
|
||||
#define SQLITE_READONLY 7 /* Attempt to write a readonly database */
|
||||
#define SQLITE_INTERRUPT 8 /* Operation terminated by sqlite_interrupt() */
|
||||
#define SQLITE_IOERR 9 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 10 /* The database disk image is malformed */
|
||||
#define SQLITE_FULL 12 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 13 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 14 /* Database lock protocol error */
|
||||
#define SQLITE_SCHEMA 16 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 17 /* Too much data for one row of a table */
|
||||
</pre></blockquote>
|
||||
|
||||
<p>Only the three core routines shown above are required to use
|
||||
@ -127,39 +135,26 @@ header file that comes in the source tree.</p>
|
||||
|
||||
<p>Use the <b>sqlite_open()</b> function to open an existing SQLite
|
||||
database or to create a new SQLite database. The first argument
|
||||
is the database name. The second argument is a constant 0666 to
|
||||
open the database for reading and writing and 0444 to open the
|
||||
database read only. The third argument is a pointer to a string
|
||||
pointer. If the third argument is not NULL and an error occurs
|
||||
is the database name. The second argument is intended to signal
|
||||
whether the database is going to be used for reading and writing
|
||||
or just for reading. But in the current implementation, the
|
||||
second argument to <b>sqlite_open</b> is ignored.
|
||||
The third argument is a pointer to a string pointer.
|
||||
If the third argument is not NULL and an error occurs
|
||||
while trying to open the database, then an error message will be
|
||||
written to memory obtained from malloc() and *errmsg will be made
|
||||
to point to this error message. The calling function is responsible
|
||||
for freeing the memory when it has finished with it.</p>
|
||||
|
||||
<p>The name of an SQLite database is normally the name of a directory
|
||||
that contains a collection of GDBM files that comprise the database.
|
||||
There is one GDBM file for each table and index in the
|
||||
database. All GDBM files end with the ".tbl" suffix. Every SQLite
|
||||
database also contains a special database table named <b>sqlite_master</b>
|
||||
stored in its own GDBM file. This special table records the database
|
||||
schema.</p>
|
||||
|
||||
<p>To create a new SQLite database, all you have to do is call
|
||||
<b>sqlite_open()</b> with the first parameter set to the name of
|
||||
an empty directory and the second parameter set to 0666. The
|
||||
directory is created automatically if it does not already exist.</p>
|
||||
|
||||
<p>Beginning with SQLite version 1.0.14, SQLite supports database
|
||||
backends other than GDBM. The only backends currently supported
|
||||
are the default GDBM driver and an in-memory hash table database.
|
||||
You may anticipate additional backends in future versions of SQLite.</p>
|
||||
|
||||
<p>An alternative database backend is specified by prepending the
|
||||
backend name and a colon to the database name argument of the
|
||||
<b>sqlite_open()</b> function. For the GDBM backend, you can
|
||||
prepend "<b>gdbm:</b>" to the directory name. To select the in-memory
|
||||
hash table backend, prepend "<b>memory:</b>" to the database name.
|
||||
Future database drivers will be selected by a similar mechanism.</p>
|
||||
<p>The name of an SQLite database is the name of a file that will
|
||||
contain the database. If the file does not exist, SQLite attempts
|
||||
to create and initialize it. If the file is read-only (due to
|
||||
permission bits or because it is located on read-only media like
|
||||
a CD-ROM) then SQLite opens the database for reading only. The
|
||||
entire SQL database is stored in a single file on the disk. But
|
||||
additional temporary files may be created during the execution of
|
||||
an SQL command in order to store the database rollback journal or
|
||||
temporary and intermediate results of a query.</p>
|
||||
|
||||
<p>The return value of the <b>sqlite_open()</b> function is a
|
||||
pointer to an opaque <b>sqlite</b> structure. This pointer will
|
||||
@ -172,6 +167,8 @@ for any reason.</p>
|
||||
<p>To close an SQLite database, call the <b>sqlite_close()</b>
|
||||
function passing it the sqlite structure pointer that was obtained
|
||||
from a prior call to <b>sqlite_open</b>.
|
||||
If a transaction is active when the database is closed, the transaction
|
||||
is rolled back.</p>
|
||||
|
||||
<h2>Executing SQL statements</h2>
|
||||
|
||||
@ -249,42 +246,69 @@ mailing list.
|
||||
that was passed into the <b>sqlite_exec()</b>.
|
||||
</p></dd>
|
||||
<dt>SQLITE_PERM</dt>
|
||||
<dd><p>This return value says that the access permissions on one of the
|
||||
GDBM files is such that the file cannot be opened.
|
||||
<dd><p>This return value says that the access permissions on the database
|
||||
file are such that the file cannot be opened.
|
||||
</p></dd>
|
||||
<dt>SQLITE_ABORT</dt>
|
||||
<dd><p>This value is returned if the callback function returns non-zero.
|
||||
</p></dd>
|
||||
<dt>SQLITE_BUSY</dt>
|
||||
<dd><p>This return code indicates that one of the underlying GDBM files
|
||||
is locked because it is currently being accessed by another thread or
|
||||
process. GDBM allows mutiple readers of the same file, but only one
|
||||
writer. So multiple processes can query an SQLite database at once.
|
||||
But only a single process can write to an SQLite database at one time.
|
||||
If an attempt is made to write to an SQLite database that another
|
||||
process is currently reading, the write is not performed and
|
||||
<b>sqlite_exec()</b> returns SQLITE_BUSY. Similarly, an attempt to read
|
||||
an SQLite database that is currently being written by another process
|
||||
will return SQLITE_BUSY. In both cases, the write or query attempt
|
||||
can be retried after the other process finishes.</p>
|
||||
<p>Note that locking is done at the file level. One process can
|
||||
write to table ABC (for example) while another process simultaneously
|
||||
reads from a different table XYZ. But you cannot have two processes reading
|
||||
and writing table ABC at the same time.
|
||||
<dd><p>This return code indicates that another program or thread has
|
||||
the database locked. SQLite allows two or more threads to read the
|
||||
database at the same time, but only one thread can have the database
|
||||
open for writing at the same time. Locking in SQLite is on the
|
||||
entire database.</p>
|
||||
</p></dd>
|
||||
<dt>SQLITE_NOMEM</dt>
|
||||
<dd><p>This value is returned if a call to <b>malloc()</b> fails.
|
||||
</p></dd>
|
||||
<dt>SQLITE_READONLY</dt>
|
||||
<dd><p>This return code indicates that an attempt was made to write to
|
||||
a database file that was originally opened for reading only. This can
|
||||
happen if the callback from a query attempts to update the table
|
||||
being queried.
|
||||
a database file that is opened for reading only.
|
||||
</p></dd>
|
||||
<dt>SQLITE_INTERRUPT</dt>
|
||||
<dd><p>This value is returned if a call to <b>sqlite_interrupt()</b>
|
||||
interrupts a database operation in progress.
|
||||
</p></dd>
|
||||
<dt>SQLITE_IOERR</dt>
|
||||
<dd><p>This value is returned if the operating system informs SQLite
|
||||
that it is unable to perform some disk I/O operation. This could mean
|
||||
that there is no more space left on the disk.
|
||||
</p></dd>
|
||||
<dt>SQLITE_CORRUPT</dt>
|
||||
<dd><p>This value is returned if SQLite detects that the database it is
|
||||
working on has become corrupted. Corruption might occur due to a rogue
|
||||
process writing to the database file or it might happen due to an
|
||||
perviously undetected logic error in of SQLite.
|
||||
</p></dd>
|
||||
<dt>SQLITE_FULL</dt>
|
||||
<dd><p>This value is returned if an insertion failed because there is
|
||||
no space left on the disk, or the database is too big to hold any
|
||||
more information. The latter case should only occur for databases
|
||||
that are larger than 2GB in size.
|
||||
</p></dd>
|
||||
<dt>SQLITE_CANTOPEN</dt>
|
||||
<dd><p>This value is returned if the database file could not be opened
|
||||
for some reason.
|
||||
</p></dd>
|
||||
<dt>SQLITE_PROTOCOL</dt>
|
||||
<dd><p>This value is returned if some other process is messing with
|
||||
file locks and has violated the file locking protocol that SQLite uses
|
||||
on its rollback journal files.
|
||||
</p></dd>
|
||||
<dt>SQLITE_SCHEMA</dt>
|
||||
<dd><p>When the database first opened, SQLite reads the database schema
|
||||
into memory and uses that schema to parse new SQL statements. If another
|
||||
process changes the schema, the command currently being processed will
|
||||
abort because the virtual machine code generated assumed the old
|
||||
schema. This is the return code for such cases. Retrying the
|
||||
command usually will clear the problem.
|
||||
</p></dd>
|
||||
<dt>SQLITE_TOOBIG</dt>
|
||||
<dd><p>SQLite cannot store more than about 64K of data in a single row
|
||||
of a single table. If you attempt to store more than 64K in a single
|
||||
row, this is the return code you get.
|
||||
</p></dd>
|
||||
</dl>
|
||||
</blockquote>
|
||||
|
||||
@ -398,23 +422,12 @@ was compiled.</p>
|
||||
|
||||
<h2>Changing the libraries response to locked files</h2>
|
||||
|
||||
<p>The GDBM library supports database locks at the file level.
|
||||
If a GDBM database file is opened for reading, then that same
|
||||
file cannot be reopened for writing until all readers have closed
|
||||
the file. If a GDBM file is open for writing, then the file cannot
|
||||
be reopened for reading or writing until it is closed.</p>
|
||||
|
||||
<p>If the SQLite library attempts to open a GDBM file and finds that
|
||||
the file is locked, the default action is to abort the current
|
||||
operation and return SQLITE_BUSY. But this is not always the most
|
||||
convenient behavior, so a mechanism exists to change it.</p>
|
||||
|
||||
<p>The <b>sqlite_busy_handler()</b> procedure can be used to register
|
||||
a busy callback with an open SQLite database. The busy callback will
|
||||
be invoked whenever SQLite tries to open a GDBM file that is locked.
|
||||
be invoked whenever SQLite tries to open a locked that is locked.
|
||||
The callback will typically do some other useful work, or perhaps sleep,
|
||||
in order to give the lock a chance to clear. If the callback returns
|
||||
non-zero, then SQLite tries again to open the GDBM file and the cycle
|
||||
non-zero, then SQLite tries again to open the database and the cycle
|
||||
repeats. If the callback returns zero, then SQLite aborts the current
|
||||
operation and returns SQLITE_BUSY.</p>
|
||||
|
||||
|
@ -1,227 +0,0 @@
|
||||
#
|
||||
# Run this Tcl script to generate the fileformat.html file.
|
||||
#
|
||||
set rcsid {$Id: fileformat.tcl,v 1.4 2000/08/04 13:49:03 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] {\&} body
|
||||
regsub -all {>} $body {\>} body
|
||||
regsub -all {<} $body {\<} body
|
||||
regsub -all {\(\(\(} $body {<font color="#00671f"><u>} body
|
||||
regsub -all {\)\)\)} $body {</u></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 : 6d1a6e03 m.n.
|
||||
data : 0c000000 10000000 18000000 2d313100 74686973 ............-11.this
|
||||
20697300 61207465 737400 is.a test.
|
||||
|
||||
key : 6d3f90e2 m?..
|
||||
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. If the data record of the index is exactly 4 bytes in size,
|
||||
then the data represents a single integer key. If the data is greater
|
||||
than 4 bytes in size, then the first 4 bytes form an integer that
|
||||
tells us how many keys are in the data. The index data record is
|
||||
always sized to be a power of 2. Unused slots at the end of the
|
||||
index data record are filled with zero.</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 : 02000000 45b4f724 6d3f90e2 00000000 ....E..$m?......
|
||||
|
||||
key : 2d313100 -11.
|
||||
data : 6d1a6e03 m.n.
|
||||
|
||||
$
|
||||
}
|
||||
|
||||
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>
|
||||
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 are unused.
|
||||
}
|
||||
|
||||
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>}
|
110
www/index.tcl
110
www/index.tcl
@ -1,13 +1,12 @@
|
||||
#
|
||||
# Run this TCL script to generate HTML for the index.html file.
|
||||
#
|
||||
set rcsid {$Id: index.tcl,v 1.38 2001/09/16 00:13:29 drh Exp $}
|
||||
set rcsid {$Id: index.tcl,v 1.39 2001/09/20 01:44:44 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head><title>SQLite: An SQL Database Library Built Atop GDBM</title></head>
|
||||
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
|
||||
<body bgcolor=white>
|
||||
<h1 align=center>SQLite: An SQL Database Library Built Atop
|
||||
<a href="http://www.gnu.org/software/gdbm/gdbm.html">GDBM</a></h1>
|
||||
<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] GMT<br>"
|
||||
set vers [lindex $argv 0]
|
||||
@ -25,6 +24,10 @@ access program (<a href="sqlite.html">sqlite</a>) that can
|
||||
be used to administer an SQLite database and which serves as
|
||||
an example of how to use the SQLite library.</p>
|
||||
|
||||
<p>SQLite is <b>not</b> a client library used to connect to a
|
||||
big database server. SQLite <b>is</b> the server. The SQLite
|
||||
library reads and writes directly to and from the database files
|
||||
on disk.</p>
|
||||
|
||||
<h2>Features</h2>
|
||||
|
||||
@ -40,18 +43,48 @@ three functions and one opaque structure.</li>
|
||||
<li>A TCL interface to the library is 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, HPUX, and WinNT.</li>
|
||||
<li>Built and tested under Linux and Win2K.</li>
|
||||
<li>No copyright on the source code. Use for any purpose.</li>
|
||||
</ul>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h2>Current Status</h2>
|
||||
puts {<h2>Download</h2>}
|
||||
|
||||
puts {<table align="right"hspace="10">
|
||||
<tr><td align="center" bgcolor="#8ee5ee">
|
||||
<table border="2"><tr><td align="center">
|
||||
<a href="sqlite.tar.gz"><big><b>Download SQLite<br>}
|
||||
puts "version $vers<br>"
|
||||
puts {Now!
|
||||
</td></tr></table>
|
||||
</td></tr>
|
||||
</table>}
|
||||
|
||||
|
||||
puts {<p>You can download a tarball containing all source
|
||||
code for SQLite
|
||||
}
|
||||
puts "version $vers"
|
||||
puts {
|
||||
(including the TCL scripts that generate the
|
||||
HTML files for this website) at <a href="sqlite.tar.gz">sqlite.tar.gz</a>.}
|
||||
puts "This is a [file size sqlite.tar.gz] byte download."
|
||||
set historical [lsort -dict [glob -nocomplain sqlite-*.tar.gz]]
|
||||
if {$historical!=""} {
|
||||
puts {The following historical versions of SQLite are also available:}
|
||||
foreach x $historical {
|
||||
puts "<a href=\"$x\">$x</a> ([file size $x] bytes)"
|
||||
}
|
||||
}
|
||||
puts {</p>}
|
||||
|
||||
puts {<h2>Current Status</h2>
|
||||
|
||||
<p>A <a href="changes.html">change history</a> is available online.
|
||||
There are currently no <em>known</em> memory leaks or debilitating bugs
|
||||
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.</p>
|
||||
is used to verify test coverage.</p>
|
||||
|
||||
<p>Known bugs:</p>
|
||||
|
||||
@ -75,16 +108,10 @@ only reached when <tt>malloc()</tt> fails.</p>
|
||||
<li>The <a href="lang.html">SQL Language</a> subset understood by SQLite.</li>
|
||||
<li>The <a href="c_interface.html">C/C++ Interface</a>.</li>
|
||||
<li>The <a href="tclsqlite.html">Tcl Interface</a>.</li>
|
||||
<li>The <a href="fileformat.html">file format</a> used by SQLite databases.</li>
|
||||
<li>The <a href="arch.html">Architecture of the SQLite Library</a> describes
|
||||
how the library is put together.</li>
|
||||
<li>A description of the <a href="opcode.html">virtual machine</a> that
|
||||
SQLite uses to access the database.</li>
|
||||
<li>Instructions for building
|
||||
<a href="crosscompile.html">SQLite for Win98/NT</a> using the
|
||||
MinGW cross-compiler. There are also instructions on
|
||||
<a href="mingw.html">building MinGW</a> in case you don't already have
|
||||
a copy.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@ -93,28 +120,22 @@ another important source of information. </p>
|
||||
}
|
||||
|
||||
puts {
|
||||
<a name="mailinglist" />
|
||||
<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">
|
||||
<table align="right">
|
||||
<tr><td align="center">
|
||||
<a href="http://www.yahoogroups.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 all source
|
||||
code for SQLite
|
||||
</td></tr>
|
||||
</table>
|
||||
<a name="mailinglist" />
|
||||
<h2>Mailing List</h2>
|
||||
<p>A mailing list has been set up on yahooGroups for discussion of
|
||||
SQLite design issues or for asking questions about SQLite.</p>
|
||||
}
|
||||
puts "version $vers"
|
||||
puts {
|
||||
(including the TCL scripts that generate the
|
||||
HTML files for this website) at <a href="sqlite.tar.gz">sqlite.tar.gz</a>.}
|
||||
puts "This is a [file size sqlite.tar.gz] byte download."
|
||||
puts {</p>
|
||||
|
||||
puts {<h2>Building From Source</h2>}
|
||||
|
||||
puts {
|
||||
<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>
|
||||
@ -128,8 +149,13 @@ $ 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>.
|
||||
<p>The Win2K version of SQLite was built using the MingW32 cross-compiler
|
||||
running under Linux. You have to give the configure script hints to make
|
||||
this work. Read the comments at the beginning of the file
|
||||
<b>configure.in</b> for additional information. The source code is
|
||||
general enough that it should be possible to compile SQLite using VC++,
|
||||
though the author has no desire or motivation to try.
|
||||
</p>
|
||||
}
|
||||
|
||||
puts {<h2>Command-line Usage Example</h2>
|
||||
@ -161,15 +187,6 @@ base$
|
||||
puts {<h2>Related Sites</h2>
|
||||
|
||||
<ul>
|
||||
<li><p>The canonical 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.sleepycat.com/">http://www.sleepycat.com/</a>
|
||||
</p></li>
|
||||
|
||||
<li><p>Here is a good <a href="http://w3.one.net/~jhoffman/sqltut.htm">
|
||||
tutorial on SQL</a>.</p></li>
|
||||
@ -180,11 +197,6 @@ puts {<h2>Related Sites</h2>
|
||||
<li><p><a href="http://www.chordate.com/gadfly.html">Gadfly</a> is another
|
||||
SQL library, similar to SQLite, except that Gadfly is written
|
||||
in Python.</p></li>
|
||||
|
||||
<li><p><a href="http://www.vogel-nest.de/tcl/qgdbm.html">Qgdbm</a> is
|
||||
a wrapper around
|
||||
<a href="http://www.vogel-nest.de/tcl/tclgdbm.html">tclgdbm</a>
|
||||
that provides SQL-like access to GDBM files.</p></li>
|
||||
</ul>}
|
||||
|
||||
puts {
|
||||
|
95
www/lang.tcl
95
www/lang.tcl
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.8 2001/05/21 13:45:10 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.9 2001/09/20 01:44:44 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -49,6 +49,7 @@ foreach {section} [lsort -index 0 -dictionary {
|
||||
{EXPLAIN explain}
|
||||
{expression expr}
|
||||
{{BEGIN TRANSACTION} transaction}
|
||||
{PRAGMA pragma}
|
||||
}] {
|
||||
puts "<li><a href=\"#[lindex $section 1]\">[lindex $section 0]</a></li>"
|
||||
}
|
||||
@ -116,41 +117,30 @@ ROLLBACK [TRANSACTION [<name>]]
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>Support for transactions in SQLite is thin. Transactions
|
||||
may not be nested. The GDBM backend does not support an atomic
|
||||
commit or rollback, but it does support locking. (Note, however,
|
||||
that the compilation instructions on this website for using GDBM under
|
||||
Windows will disable locking.) The MEM backend has no transaction
|
||||
support and silently ignores all requests to begin or end
|
||||
transactions. A new backend is currently under
|
||||
development for SQLite 2.0 that will support both atomic commits and rollback,
|
||||
but that driver is not yet available.</p>
|
||||
<p>Beginning in version 2.0, SQLite supports transactions with
|
||||
rollback and atomic commit. However, only a single level of
|
||||
transaction is required. In other words, transactions
|
||||
may not be nested.
|
||||
</p>
|
||||
|
||||
<p>Under GDBM, starting a transaction just locks all
|
||||
tables that are either read or written during the course of the
|
||||
transaction. The locks are removed when the transaction is ended.
|
||||
Thus, transactions can be used to make changes to multiple tables
|
||||
with the assurance that other threads or processes will not touch
|
||||
the same tables at the same time. For example:</p>
|
||||
<p>
|
||||
No changes can be made to the database except within a transaction.
|
||||
Any command that changes the database (basically, any SQL command
|
||||
other than SELECT) will automatically starts a transaction if
|
||||
when is not already in effect. Automatically stared transactions
|
||||
are committed at the conclusion of the command.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<b>SELECT data1, data2, ... FROM table1 WHERE ...;</b><br>
|
||||
... Make a decision to update the table ...<br>
|
||||
<b>BEGIN TRANSACTION;<br>
|
||||
SELECT data1, data2, ... FROM table1 WHERE ...;</b><br>
|
||||
... Make sure no other process changed the table in between
|
||||
the first SELECT and the BEGIN TRANSACTION. ...<br>
|
||||
<b>UPDATE table1 SET data1=... WHERE ...;<br>
|
||||
END TRANSACTION;</b>
|
||||
</blockquote>
|
||||
|
||||
<p>In the code above, the <b>table1</b> table is locked by
|
||||
the second SELECT because of the transaction. Thus we know that
|
||||
no other process has modified <b>table1</b> when the UPDATE
|
||||
occurs. The END TRANSACTION releases the lock.</p>
|
||||
<p>
|
||||
Transactions can be started manually using the BEGIN TRANSACTION
|
||||
command. Such transactions persist until a COMMIT or ROLLBACK
|
||||
or until an error occurs or the database is closed. If an
|
||||
error is encountered or the database is closed, the transaction
|
||||
is automatically rolled back. The END TRANSACTION command is
|
||||
a alias for COMMIT.
|
||||
</p>
|
||||
}
|
||||
|
||||
|
||||
Section COPY copy
|
||||
|
||||
Syntax {sql-statement} {
|
||||
@ -195,8 +185,8 @@ 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
|
||||
to indicate sort order, but since GDBM does not implement ordered keys,
|
||||
these keywords are ignored.</p>
|
||||
to indicate sort order, but the sort order is ignored in the current
|
||||
implementation.</p>
|
||||
|
||||
<p>There are no arbitrary limits on the number of indices that can be
|
||||
attached to a single table, nor on the number of columns in an index.</p>
|
||||
@ -248,14 +238,11 @@ is stored as null-terminated strings. The constraints are also ignored,
|
||||
except that the PRIMARY KEY constraint will cause an index to be automatically
|
||||
created that implements the primary key and the DEFAULT constraint
|
||||
which specifies a default value to use when doing an INSERT.
|
||||
The name of the primary
|
||||
key index will be the table name
|
||||
with "<b>__primary_key</b>" appended. The index used for a primary key
|
||||
does not show up in the <b>sqlite_master</b> table, but a GDBM file is
|
||||
created for that index.</p>
|
||||
</p>
|
||||
|
||||
<p>There are no arbitrary limits on the size of columns, on the number
|
||||
of columns, or on the number of constraints in a table.</p>
|
||||
<p>There are no arbitrary limits on the number
|
||||
of columns or on the number of constraints in a table.
|
||||
The total amount of data in a single row is limited to 65535 bytes.</p>
|
||||
|
||||
<p>The exact text
|
||||
of each CREATE TABLE statement is stored in the <b>sqlite_master</b>
|
||||
@ -524,8 +511,8 @@ the FROM keyword. If more than one table is specified, then the
|
||||
query is against the join of the various tables.</p>
|
||||
|
||||
<p>The WHERE clause can be used to limit the number of rows over
|
||||
which the query operates. Note that because of limitations of
|
||||
GDBM (it uses hashing not b-trees) indices will only be used to
|
||||
which the query operates. In the current implementation,
|
||||
indices will only be used to
|
||||
optimize the query if WHERE expression contains equality comparisons
|
||||
connected by the AND operator.</p>
|
||||
|
||||
@ -585,15 +572,21 @@ VACUUM [<index-or-table-name>]
|
||||
puts {
|
||||
<p>The VACUUM command is an SQLite extension modelled after a similar
|
||||
command found in PostgreSQL. If VACUUM is invoked with the name of a
|
||||
table or index, then the <b>gdbm_reorganize()</b> function is called
|
||||
on the corresponding GDBM file. If VACUUM is invoked with no arguments,
|
||||
then <b>gdbm_reorganize()</b> is called for every GDBM file in the database.</p>
|
||||
table or index then it is suppose to clean up the named table or index.
|
||||
In the current implementation, VACUUM is a no-op.
|
||||
</p>
|
||||
}
|
||||
|
||||
<p>It is a good idea to run VACUUM after creating large indices,
|
||||
especially indices where a single index value refers to many
|
||||
entries in the data table. Reorganizing these indices will make
|
||||
the underlying GDBM file much smaller and will help queries to
|
||||
run much faster.</p>
|
||||
Section PRAGMA pragma
|
||||
|
||||
Syntax {sql-statement} {
|
||||
PRAGMA <name> = <value>
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>The PRAGMA command is used to modify the operation of the SQLite library.
|
||||
Additional documentation on the PRAMGA statement is forthcoming.
|
||||
</p>
|
||||
}
|
||||
|
||||
puts {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: opcode.tcl,v 1.4 2000/07/30 20:04:43 drh Exp $}
|
||||
set rcsid {$Id: opcode.tcl,v 1.5 2001/09/20 01:44:44 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -60,7 +60,11 @@ available. If you are looking for a narrative description
|
||||
of how the virtual machine works, you should read the tutorial
|
||||
and not this document. Once you have a basic idea of what the
|
||||
virtual machine does, you can refer back to this document for
|
||||
the details on a particular opcode.</p>
|
||||
the details on a particular opcode.
|
||||
Unfortunately, the virtual machine tutorial was written for
|
||||
SQLite version 1.0. There are substantial changes in the virtual
|
||||
machine for version 2.0 and the document has not been updated.
|
||||
</p>
|
||||
|
||||
<p>The source code to the virtual machine is in the <b>vdbe.c</b> source
|
||||
file. All of the opcode definitions further down in this document are
|
||||
@ -84,23 +88,27 @@ Execution continues until (1) a Halt instruction is seen, or
|
||||
(2) the program counter becomes one greater than the address of
|
||||
last instruction, or (3) there is an execution error.
|
||||
When the virtual machine halts, all memory
|
||||
that it allocated is released and all database files it may
|
||||
have had open are closed.</p>
|
||||
that it allocated is released and all database cursors it may
|
||||
have had open are closed. If the execution stopped due to an
|
||||
error, any pending transactions are terminated and changes made
|
||||
to the database are rollback.</p>
|
||||
|
||||
<p>The virtual machine also contains an operand stack of unlimited
|
||||
depth. Many of the opcodes use operands from the stack. See the
|
||||
individual opcode descriptions for details.</p>
|
||||
|
||||
<p>The virtual machine can have zero or more cursors. Each cursor
|
||||
is a pointer into a single GDBM file. There can be multiple
|
||||
cursors pointing at the same file.
|
||||
All cursors operate independently, even cursors pointing to the same file.
|
||||
The only way for the virtual machine to interact with a GDBM
|
||||
is a pointer into a single table or index within the database.
|
||||
There can be multiple cursors pointing at the same index or table.
|
||||
All cursors operate independently, even cursors pointing to the same
|
||||
indices or tables.
|
||||
The only way for the virtual machine to interact with a database
|
||||
file is through a cursor.
|
||||
Instructions in the virtual
|
||||
machine can create a new cursor (Open), read data from a cursor
|
||||
(Field), advance the cursor to the next entry in the GDBM file
|
||||
(Next), and many other operations. All cursors are automatically
|
||||
(Column), advance the cursor to the next entry in the table
|
||||
(Next) or index (NextIdx), and many other operations.
|
||||
All cursors are automatically
|
||||
closed when the virtual machine terminates.</p>
|
||||
|
||||
<p>The virtual machine contains an arbitrary number of fixed memory
|
||||
@ -119,14 +127,12 @@ historical accident. In practice no more than one sorter
|
||||
|
||||
<p>The virtual machine may contain an arbitrary number of "Lists".
|
||||
Each list stores a list of integers. Lists are used to hold the
|
||||
GDBM keys for records of a GDBM file that needs to be modified.
|
||||
(See the <a href="fileformat.html">file format</a> description for
|
||||
more information on GDBM keys in SQLite table files.)
|
||||
rowids for records of a database table that needs to be modified.
|
||||
The WHERE clause of an UPDATE or DELETE statement scans through
|
||||
the table and writes the GDBM key of every record to be modified
|
||||
the table and writes the rowid of every record to be modified
|
||||
into a list. Then the list is played back and the table is modified
|
||||
in a separate step. It is necessary to do this in two steps since
|
||||
making a change to a GDBM file can alter the scan order.</p>
|
||||
making a change to a database table can alter the scan order.</p>
|
||||
|
||||
<p>The virtual machine can contain an arbitrary number of "Sets".
|
||||
Each set holds an arbitrary number of strings. Sets are used to
|
||||
@ -174,23 +180,30 @@ Code {
|
||||
$ (((sqlite ex1)))
|
||||
sqlite> (((.explain)))
|
||||
sqlite> (((explain delete from tbl1 where two<20;)))
|
||||
addr opcode p1 p2 p3
|
||||
---- ------------ ----- ----- -------------------------------------
|
||||
0 ListOpen 0 0
|
||||
1 Open 0 1 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
|
||||
addr opcode p1 p2 p3
|
||||
---- ------------ ----- ----- ----------------------------------------
|
||||
0 Transaction 0 0
|
||||
1 VerifyCookie 990 0
|
||||
2 ListOpen 0 0
|
||||
3 Open 0 31 tbl1
|
||||
4 VerifyCookie 990 0
|
||||
5 Rewind 0 0
|
||||
6 Next 0 13
|
||||
7 Column 0 1
|
||||
8 Integer 20 0
|
||||
9 Ge 0 6
|
||||
10 Recno 0 0
|
||||
11 ListWrite 0 0
|
||||
12 Goto 0 6
|
||||
13 Close 0 0
|
||||
14 ListRewind 0 0
|
||||
15 Open 0 31
|
||||
16 ListRead 0 20
|
||||
17 MoveTo 0 0
|
||||
18 Delete 0 0
|
||||
19 Goto 0 16
|
||||
20 ListClose 0 0
|
||||
21 Commit 0 0
|
||||
}
|
||||
|
||||
puts {
|
||||
@ -202,10 +215,18 @@ viewable.</p>
|
||||
<p>If <b>sqlite</b> has been compiled without the "-DNDEBUG=1" option
|
||||
(that is, with the NDEBUG preprocessor macro not defined) then you
|
||||
can put the SQLite virtual machine in a mode where it will trace its
|
||||
execution by writing messages to standard output. There are special
|
||||
comments to turn tracing on and off. Use the <b>--vdbe-trace-on--</b>
|
||||
comment to turn tracing on and the <b>--vdbe-trace-off--</b> comment
|
||||
to turn tracing back off.</p>
|
||||
execution by writing messages to standard output. The non-standard
|
||||
SQL "PRAGMA" comments can be used to turn tracing on and off. To
|
||||
turn tracing on, enter:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
PRAGMA vdbe_trace=on;
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
You can turn tracing back off by entering a similar statement but
|
||||
changing the value "on" to "off".</p>
|
||||
|
||||
<h2>The Opcodes</h2>
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the tclsqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: tclsqlite.tcl,v 1.3 2000/10/23 13:16:33 drh Exp $}
|
||||
set rcsid {$Id: tclsqlite.tcl,v 1.4 2001/09/20 01:44:44 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -44,27 +44,8 @@ way widgets are created in Tk.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The name of the database is usually either the name of a directory
|
||||
that will contain the GDBM files that comprise the database, or it is the
|
||||
name of the directory prefaced by "<b>gdbm:</b>". The second form
|
||||
of the name is a new feature beginning in SQLite version 1.0.14 that
|
||||
allows you to select alternative database backends. The default
|
||||
backend is GDBM. But you can also select to store the database in
|
||||
a hash table in memory by using the prefix "<b>memory:</b>".
|
||||
Other backends may be added in the future.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Every time you open an SQLite database with the <b>memory:</b> prefix
|
||||
on the database name, you get a new in-memory database. This is true
|
||||
even if you open two databases with the same name. Furthermore,
|
||||
an in-memory database is automatically deleted when the database is
|
||||
closed and so is not useful for persistant storage like a normal
|
||||
database. But the use of an in-memory SQL database does give Tcl/Tk
|
||||
a powerful new data storage mechanism that can do things that are
|
||||
difficult to do with only Tcl array variables. In fact, the
|
||||
hash-table backend for SQLite was created for the sole purpose of
|
||||
providing better data structure support to the Tcl language.
|
||||
The name of the database is just the name of a disk file in which
|
||||
the database is stored.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -229,19 +210,17 @@ will wait for locks to clear before giving up on a database transaction.
|
||||
The default timeout is 0 millisecond. (In other words, the default behavior
|
||||
is not to wait at all.)</p>
|
||||
|
||||
<p>The GDBM backend allows multiple simultaneous
|
||||
<p>The SQlite database allows multiple simultaneous
|
||||
readers or a single writer but not both. If any process is writing to
|
||||
the database no other process is allows to read or write. If any process
|
||||
is reading the database other processes are allowed to read but not write.
|
||||
Each GDBM file is locked separately. Because each SQL table is stored as
|
||||
a separate file, it is possible for different processes to write to different
|
||||
database tables at the same time, just not the same table.</p>
|
||||
The entire database shared a single lock.</p>
|
||||
|
||||
<p>When SQLite tries to open a GDBM file and finds that it is locked, it
|
||||
<p>When SQLite tries to open a database and finds that it is locked, it
|
||||
can optionally delay for a short while and try to open the file again.
|
||||
This process repeats until the query times out and SQLite returns a
|
||||
failure. The timeout is adjustable. It is set to 0 by default so that
|
||||
if a GDBM file is locked, the SQL statement fails immediately. But you
|
||||
if the database is locked, the SQL statement fails immediately. But you
|
||||
can use the "timeout" method to change the timeout value to a positive
|
||||
number. For example:</p>
|
||||
|
||||
@ -253,14 +232,14 @@ would be 2 seconds.</p>
|
||||
|
||||
<h2>The "busy" method</h2>
|
||||
|
||||
<p>The "busy" method, like "timeout", only comes into play when a GDBM
|
||||
file is locked. But the "busy" method gives the programmer much more
|
||||
<p>The "busy" method, like "timeout", only comes into play when the
|
||||
database is locked. But the "busy" method gives the programmer much more
|
||||
control over what action to take. The "busy" method specifies a callback
|
||||
Tcl procedure that is invoked whenever SQLite tries to open a locked
|
||||
GDBM file. This callback can do whatever is desired. Presumably, the
|
||||
database. This callback can do whatever is desired. Presumably, the
|
||||
callback will do some other useful work for a short while then return
|
||||
so that the lock can be tried again. The callback procedure should
|
||||
return "0" if it wants SQLite to try again to open the GDBM file and
|
||||
return "0" if it wants SQLite to try again to open the database and
|
||||
should return "1" if it wants SQLite to abandon the current operation.
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user