-C Fix\sfor\sbug\s#16:\sCheck\sfor\sinvalid\sfunctions\sin\sthe\sVALUES\sclause\sof\san\nINSERT\sstatement.\s(CVS\s525)
-D 2002-04-12T03:55:16
+C Fix\sfor\sbug\s#15:\sAdd\sthe\ssqlite_changes()\sAPI\sfunction\sfor\sretrieving\sthe\nnumber\sof\srows\sthat\schanged\sin\sthe\sprevious\soperation.\s(CVS\s526)
+D 2002-04-12T10:08:59
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
F src/btree.c 7dd7ddc66459982dd0cb9800958c1f8d65a32d9f
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
F src/build.c d01b81f41481e733e27ab2fa8e1bfcc64f24257d
-F src/delete.c 577da499162291c1855f0b304b211bffcf9da945
+F src/delete.c 6a6b8192cdff5e4b083da3bc63de099f3790d01f
F src/expr.c e7a1e22bc2ebcd789f0f8c0db544cf16ad664054
F src/func.c dca9df811298cd0beb3724d40cee348e884352b2
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
-F src/insert.c 80105ff6a8bdabe8122948b0066fb1914f9b86c7
-F src/main.c b21019084b93fe685a8a25217d01f6958584ae9b
+F src/insert.c 31233f44fc79edbb43523a830e54736a8e222ff4
+F src/main.c df43fe585d2bfb925c837b6822783c0ee3dd6e1c
F src/md5.c b2b1a34fce66ceca97f4e0dabc20be8be7933c92
F src/os.c 5ab8b6b4590d0c1ab8e96c67996c170e4462e0fc
F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
F src/select.c 92aef3f69e90dc065d680d88b1f075409e9249bb
F src/shell.c 994ca7c8c40c40a95011812013fbbf9828f5a0e7
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
-F src/sqlite.h.in 1dae50411aee9439860d7fbe315183c582d27197
-F src/sqliteInt.h 73e7d0f39a3c11d395fc422986959261bd193eba
+F src/sqlite.h.in ffcacf73b5ed1a4939205d29a704a185758fa6a6
+F src/sqliteInt.h e47ca9267a4c4a98e9f8d90c2df994a18f23d699
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
-F src/tclsqlite.c df847b71b28277f1cfa1ee1e3e51452ffe5a9a26
+F src/tclsqlite.c c9e9039762d9866eae70bf782237d0206a13f57e
F src/test1.c d46ab7a82a9c16a3b1ee363cb4c0f98c5ff65743
F src/test2.c d410dbd8a90faa466c3ab694fa0aa57f5a773aa6
F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
F src/tokenize.c 5624d342601f616157ba266abccc1368a5afee70
F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb
F src/util.c b34cd91387bbfdc79319ea451a7d120cef478120
-F src/vdbe.c ccc394cf72b5c43b71309fecc35cdf5cd252e154
+F src/vdbe.c 9213ff1ab136eabcf3e8a58157765a01274bf8e9
F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc
F src/where.c 9d36f6c9fea4af71501770c13089f824cb9b033c
F test/all.test 6aa106eee4d7127afa5cee97c51a783a79694ead
F test/btree.test bf326f546a666617367a7033fa2c07451bd4f8e1
F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080
F test/btree3.test 9caa9e22491dd8cd8aa36d7ac3b48b089817c895
-F test/conflict.test 3383ac08da14cdba11bb4c9495583cf87f67afb1
+F test/conflict.test 5149646703d3930c9111068b5cda7e2e938476e3
F test/copy.test b3cefcb520c64d7e7dfedbab06b4d4c31fa5b99a
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
F test/expr.test 846795016b5993a7411f772eebe82ab67bd7230a
F test/in.test c09312672e3f0709fa02c8e2e9cd8fb4bd6269aa
F test/index.test c8a471243bbf878974b99baf5badd59407237cf3
F test/insert.test c36d534a4ab58c2cd452a273e51b2b0dd1ede1f9
-F test/insert2.test 2f02b1e0dbfba3e8c76496209be5f4010b584181
+F test/insert2.test eb8481878a7f52ccb4e3346f87550f5afdd77f76
F test/intpkey.test 31b5f28b2c44273e6695cf36ab2e4133aee7753c
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
F test/limit.test a930f3eba2a7691c8397ccab33710b931589566a
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
F test/table.test 17b0b6eafa3faaee5545b7a94e6c1ff73f0880f3
F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
-F test/tclsqlite.test ca8dd89b02ab68bd4540163c24551756a69f6783
+F test/tclsqlite.test 79deeffd7cd637ca0f06c5dbbf2f44d272079533
F test/temptable.test 0e9934283259a5e637eec756a7eefd6964c0f79b
F test/tester.tcl dc1b56bd628b487e4d75bfd1e7480b5ed8810ac6
F test/trans.test ae0b9a82d5d34122c3a3108781eb8d078091ccee
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
-F www/c_interface.tcl 567cda531aac9d68a61ef02e26c6b202bd856db2
+F www/c_interface.tcl 79f63ffa8c6e7adb9e3449ff325d093cfb0ce3e3
F www/changes.tcl 4083f03195f0ae36411e095a2d18e5fb4a3c40d9
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
F www/faq.tcl fb1e92e2f604546694f83a36d969492f52fb685d
F www/formatchng.tcl 2ce21ff30663fad6618198fe747ce675df577590
F www/index.tcl 2a9653ebeeaba3aca3401f476ba0e0e4acb40929
-F www/lang.tcl 75615f1acd8a428d93546ad9edfbf8f78ee1e2df
+F www/lang.tcl 2d4654255ad1ec7f58d02dc41b59528c0ee6ea44
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
-F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
+F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P bb83642e9a6c1c9ade861618496933c9f922a8f8
-R f474a54633adfc730f9670e6001e85d7
+P 43a77f019d34e1a6b3f502ad0ec31a00c8fdbe6e
+R f1c51fffab48448616c03a8f7db64a46
U drh
-Z ee5b859e30a1d5d36bceb3c81154e192
+Z fa8a7c3395ff2734ddb7f18394f23f2a
-43a77f019d34e1a6b3f502ad0ec31a00c8fdbe6e
\ No newline at end of file
+6e71493b9dc77d508c3ce90562766789e87e6d80
\ No newline at end of file
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
-** $Id: delete.c,v 1.29 2002/03/03 18:59:40 drh Exp $
+** $Id: delete.c,v 1.30 2002/04/12 10:08:59 drh Exp $
*/
#include "sqliteInt.h"
}
end = sqliteVdbeMakeLabel(v);
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
- sqliteGenerateRowDelete(v, pTab, base);
+ sqliteGenerateRowDelete(v, pTab, base, 1);
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
sqliteVdbeResolveLabel(v, end);
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
void sqliteGenerateRowDelete(
Vdbe *v, /* Generate code into this VDBE */
Table *pTab, /* Table containing the row to be deleted */
- int base /* Cursor number for the table */
+ int base, /* Cursor number for the table */
+ int count /* Increment the row change counter */
){
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
sqliteGenerateRowIndexDelete(v, pTab, base, 0);
- sqliteVdbeAddOp(v, OP_Delete, base, 0);
+ sqliteVdbeAddOp(v, OP_Delete, base, count);
}
/*
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.51 2002/04/12 03:55:16 drh Exp $
+** $Id: insert.c,v 1.52 2002/04/12 10:08:59 drh Exp $
*/
#include "sqliteInt.h"
break;
}
case OE_Replace: {
- sqliteGenerateRowDelete(v, pTab, base);
+ sqliteGenerateRowDelete(v, pTab, base, 0);
if( isUpdate ){
sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
sqliteVdbeAddOp(v, OP_IdxPut, base+i+1, 0);
}
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
- sqliteVdbeAddOp(v, OP_PutIntKey, base, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, base, 1);
if( isUpdate && recnoChng ){
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
}
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.68 2002/03/06 22:01:36 drh Exp $
+** $Id: main.c,v 1.69 2002/04/12 10:08:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
return db->lastRowid;
}
+/*
+** Return the number of changes in the most recent call to sqlite_exec().
+*/
+int sqlite_changes(sqlite *db){
+ return db->nChange;
+}
+
/*
** Close an existing SQLite database
*/
return rc;
}
}
+ if( db->recursionDepth==0 ){ db->nChange = 0; }
+ db->recursionDepth++;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
sParse.pBe = db->pBe;
if( sParse.rc==SQLITE_SCHEMA ){
clearHashTable(db, 1);
}
+ db->recursionDepth--;
return sParse.rc;
}
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.29 2002/03/08 02:12:00 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.30 2002/04/12 10:08:59 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
*/
int sqlite_last_insert_rowid(sqlite*);
+/*
+** This function returns the number of database rows that were changed
+** (or inserted or deleted) by the most recent called sqlite_exec().
+**
+** All changes are counted, even if they were later undone by a
+** ROLLBACK or ABORT. Except, changes associated with creating and
+** dropping tables are not counted.
+**
+** If a callback invokes sqlite_exec() recursively, then the changes
+** in the inner, recursive call are counted together with the changes
+** in the outer call.
+**
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table. (This is much faster than going
+** through and deleting individual elements form the table.) Because of
+** this optimization, the change count for "DELETE FROM table" will be
+** zero regardless of the number of elements that were originally in the
+** table. To get an accurate count of the number of rows deleted, use
+** "DELETE FROM table WHERE 1" instead.
+*/
+int sqlite_changes(sqlite*);
+
/* If the parameter to this routine is one of the return value constants
** defined above, then this routine returns a constant text string which
** descripts (in English) the meaning of the return value.
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.104 2002/03/12 23:10:05 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.105 2002/04/12 10:08:59 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
int lastRowid; /* ROWID of most recent insert */
int priorNewRowid; /* Last randomly generated ROWID */
int onError; /* Default conflict algorithm */
+ int nChange; /* Number of rows changed */
+ int recursionDepth; /* Number of nested calls to sqlite_exec() */
};
/*
void sqliteRollbackTransaction(Parse*);
char *sqlite_mprintf(const char *, ...);
int sqliteExprIsConstant(Expr*);
-void sqliteGenerateRowDelete(Vdbe*, Table*, int);
+void sqliteGenerateRowDelete(Vdbe*, Table*, int, int);
void sqliteGenerateRowIndexDelete(Vdbe*, Table*, int, char*);
void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int);
*************************************************************************
** A TCL Interface to SQLite
**
-** $Id: tclsqlite.c,v 1.30 2002/03/11 02:06:13 drh Exp $
+** $Id: tclsqlite.c,v 1.31 2002/04/12 10:08:59 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
SqliteDb *pDb = (SqliteDb*)cd;
int choice;
static char *DB_optStrs[] = {
- "busy", "close", "complete", "eval", "last_insert_rowid", "timeout", 0
+ "busy", "changes", "close", "complete",
+ "eval", "last_insert_rowid", "timeout", 0
};
enum DB_opts {
- DB_BUSY, DB_CLOSE, DB_COMPLETE, DB_EVAL, DB_LAST_INSERT_ROWID, DB_TIMEOUT
+ DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMPLETE,
+ DB_EVAL, DB_LAST_INSERT_ROWID, DB_TIMEOUT
};
if( objc<2 ){
break;
}
+ /*
+ ** $db changes
+ **
+ ** Return the number of rows that were modified, inserted, or deleted by
+ ** the most recent "eval".
+ */
+ case DB_CHANGES: {
+ Tcl_Obj *pResult;
+ int nChange;
+ if( objc!=2 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+ nChange = sqlite_changes(pDb->db);
+ pResult = Tcl_GetObjResult(interp);
+ Tcl_SetIntObj(pResult, nChange);
+ break;
+ }
+
/* $db close
**
** Shutdown the database
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.137 2002/04/09 03:15:07 drh Exp $
+** $Id: vdbe.c,v 1.138 2002/04/12 10:09:00 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** stack. The key is the next value down on the stack. The key must
** be an integer. The stack is popped twice by this instruction.
**
-** If P2==1 then overwriting is prohibited. If a prior entry with
-** the same key exists, an SQLITE_CONSTRAINT exception is raised.
+** If P2==1 then the row change count is incremented. If P2==0 the
+** row change count is unmodified.
*/
-/* Opcode: PutStrKey P1 P2 *
+/* Opcode: PutStrKey P1 * *
**
** Write an entry into the database file P1. A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten. The data is the value on the top of the
** stack. The key is the next value down on the stack. The key must
** be a string. The stack is popped twice by this instruction.
-**
-** If P2==1 then overwriting is prohibited. If a prior entry with
-** the same key exists, an SQLITE_CONSTRAINT exception is raised.
*/
case OP_PutIntKey:
case OP_PutStrKey: {
iKey = intToKey(aStack[nos].i);
zKey = (char*)&iKey;
db->lastRowid = aStack[nos].i;
- }
- if( pOp->p2 ){
- int res;
- rc = sqliteBtreeMoveto(p->aCsr[i].pCursor, zKey, nKey, &res);
- if( res==0 && rc==SQLITE_OK ){
- rc = SQLITE_CONSTRAINT;
- }
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
+ if( pOp->p2 ) db->nChange++;
}
rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey,
zStack[tos], aStack[tos].n);
break;
}
-/* Opcode: Delete P1 * *
+/* Opcode: Delete P1 P2 *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op. Hence it is OK to delete
** a record from within an Next loop.
+**
+** The row change counter is incremented if P2==1 and is unmodified
+** if P2==0.
*/
case OP_Delete: {
int i = pOp->p1;
if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
rc = sqliteBtreeDelete(p->aCsr[i].pCursor);
}
+ if( pOp->p2 ) db->nChange++;
break;
}
# This file implements tests for the conflict resolution extension
# to SQLite.
#
-# $Id: conflict.test,v 1.10 2002/04/09 03:28:01 drh Exp $
+# $Id: conflict.test,v 1.11 2002/04/12 10:09:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
UPDATE OR IGNORE t1 SET a=1000;
}
} {1}
+do_test conflict-7.2.1 {
+ db changes
+} {1}
do_test conflict-7.3 {
execsql {
SELECT b FROM t1 WHERE a=1000;
UPDATE OR REPLACE t1 SET a=1001;
}
} {50}
+do_test conflict-7.5.1 {
+ db changes
+} {50}
do_test conflict-7.6 {
execsql {
SELECT b FROM t1 WHERE a=1001;
SELECT count(*) FROM t1;
}
} {1}
+do_test conflict-7.7.1 {
+ db changes
+} {0}
# Make sure the row count is right for rows that are ignored on
# an insert.
INSERT OR IGNORE INTO t1 VALUES(2,3);
}
} {1}
+do_test conflict-8.1.1 {
+ db changes
+} {1}
do_test conflict-8.2 {
execsql {
INSERT OR IGNORE INTO t1 VALUES(2,4);
}
} {0}
+do_test conflict-8.2.1 {
+ db changes
+} {0}
do_test conflict-8.3 {
execsql {
INSERT OR REPLACE INTO t1 VALUES(2,4);
}
} {1}
+do_test conflict-8.3.1 {
+ db changes
+} {1}
do_test conflict-8.4 {
execsql {
INSERT OR IGNORE INTO t1 SELECT * FROM t1;
}
} {0}
+do_test conflict-8.4.1 {
+ db changes
+} {0}
do_test conflict-8.5 {
execsql {
INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
}
} {2}
+do_test conflict-8.5.1 {
+ db changes
+} {2}
do_test conflict-8.6 {
execsql {
INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
}
} {3}
+do_test conflict-8.6.1 {
+ db changes
+} {3}
do_test insert-99.1 {
set x [execsql {PRAGMA integrity_check}]
# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
-# $Id: insert2.test,v 1.8 2002/03/03 02:49:52 drh Exp $
+# $Id: insert2.test,v 1.9 2002/04/12 10:09:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {6}
do_test insert2-1.1.2 {
+ db changes
+} {6}
+do_test insert2-1.1.3 {
execsql {SELECT * FROM t1 ORDER BY log}
} {0 1 1 1 2 2 3 4 4 8 5 4}
INSERT INTO t4 VALUES(9,18);
INSERT INTO t4 VALUES(10,20);
COMMIT;
+ }
+ db changes
+} {9}
+do_test insert2-3.2.1 {
+ execsql {
SELECT count(*) FROM t4;
}
} {10}
ROLLBACK;
}
} {1}
+do_test insert2-3.8 {
+ db changes
+} {159}
finish_test
# interface is pretty well tested. This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
-# $Id: tclsqlite.test,v 1.5 2002/01/16 21:00:28 drh Exp $
+# $Id: tclsqlite.test,v 1.6 2002/04/12 10:09:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tcl-1.2 {
set v [catch {db bogus} msg]
lappend v $msg
-} {1 {bad option "bogus": must be busy, close, complete, eval, last_insert_rowid, or timeout}}
+} {1 {bad option "bogus": must be busy, changes, close, complete, eval, last_insert_rowid, or timeout}}
do_test tcl-1.3 {
execsql {CREATE TABLE t1(a int, b int)}
execsql {INSERT INTO t1 VALUES(10,20)}
#
# Run this Tcl script to generate the sqlite.html file.
#
-set rcsid {$Id: c_interface.tcl,v 1.25 2002/03/04 02:26:17 drh Exp $}
+set rcsid {$Id: c_interface.tcl,v 1.26 2002/04/12 10:09:00 drh Exp $}
puts {<html>
<head>
<blockquote><pre>
int sqlite_last_insert_rowid(sqlite*);
+int sqlite_changes(sqlite*);
+
int sqlite_get_table(
sqlite*,
char *sql,
for the most recent INSERT statement using the
<b>sqlite_last_insert_rowid()</b> API function.</p>
+<h2>The number of rows that changed</h2>
+
+<p>The <b>sqlite_changes()</b> API function returns the number of rows
+that were inserted, deleted, or modified during the most recent
+<b>sqlite_exec()</b> call. The number reported includes any changes
+that were later undo by a ROLLBACK or ABORT. But rows that are
+deleted because of a DROP TABLE are <em>not</em> counted.</p>
+
+<p>SQLite implements the command "<b>DELETE FROM table</b>" (without
+a WHERE clause) by dropping the table then recreating it.
+This is much faster than deleting the elements of the table individually.
+But it also means that the value returned from <b>sqlite_changes()</b>
+will be zero regardless of the number of elements that were originally
+in the table. If an accurate count of the number of elements deleted
+is necessary, use "<b>DELETE FROM table WHERE 1</b>" instead.</p>
+
<h2>Querying without using a callback function</h2>
<p>The <b>sqlite_get_table()</b> function is a wrapper around
#
# Run this Tcl script to generate the sqlite.html file.
#
-set rcsid {$Id: lang.tcl,v 1.31 2002/04/06 14:10:48 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.32 2002/04/12 10:09:00 drh Exp $}
puts {<html>
<head>
<p>When on, the COUNT_CHANGES pragma causes the callback function to
be invoked once for each DELETE, INSERT, or UPDATE operation. The
argument is the number of rows that were changed.</p>
+ <p>This pragma may be removed from future versions of SQLite.
+ Consider using the <b>sqlite_changes()</b> API function instead.</p></li>
<li><p><b>PRAGMA default_cache_size;
<br>PRAGMA default_cache_size = </b><i>Number-of-pages</i><b>;</b></p>
#
# Run this Tcl script to generate the tclsqlite.html file.
#
-set rcsid {$Id: tclsqlite.tcl,v 1.6 2002/01/16 21:00:28 drh Exp $}
+set rcsid {$Id: tclsqlite.tcl,v 1.7 2002/04/12 10:09:00 drh Exp $}
puts {<html>
<head>
<p>
Once an SQLite database is open, it can be controlled using
-methods of the <i>dbcmd</i>. There are currently 6 methods
+methods of the <i>dbcmd</i>. There are currently 7 methods
defined:</p>
<p>
<ul>
<li> busy
+<li> changes
<li> close
<li> complete
<li> eval
<p>The "last_insert_rowid" method returns an integer which is the ROWID
of the most recently inserted database row.</p>
+<h2>The "changes" method</h2>
+
+<p>The "changes" method returns an integer which is the number of rows
+in the database that were inserted, deleted, and/or modified by the most
+recent "eval" method.</p>
+
}
puts {