]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update sqlite3_changes() to match the documentation and add
authordanielk1977 <danielk1977@noemail.net>
Mon, 21 Jun 2004 06:50:26 +0000 (06:50 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 21 Jun 2004 06:50:26 +0000 (06:50 +0000)
sqlite3_total_changes(). (CVS 1645)

FossilOrigin-Name: ae2f4a0943854fedbbb6fab1dc3aaf972722ed95

20 files changed:
manifest
manifest.uuid
src/delete.c
src/func.c
src/insert.c
src/main.c
src/sqlite.h.in
src/sqliteInt.h
src/tclsqlite.c
src/trigger.c
src/update.c
src/vdbe.c
src/vdbe.h
src/vdbeInt.h
src/vdbeaux.c
test/capi2.test
test/conflict.test
test/insert2.test
test/laststmtchanges.test
test/tclsqlite.test

index ac06a64241b029c99d9caac802eb75c547473fee..7f991215792785b0f6580e53fa7934a247d2fd2a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C fix\sfulltest\serror\sby\srestoring\sunset\s(CVS\s1644)
-D 2004-06-20T03:06:18
+C Update\ssqlite3_changes()\sto\smatch\sthe\sdocumentation\sand\sadd\nsqlite3_total_changes().\s(CVS\s1645)
+D 2004-06-21T06:50:27
 F Makefile.in d69d53c543518c1572ee0a8e8723d7e00bdb2266
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -30,15 +30,15 @@ F src/btree.c 0cf8a52a57a7eb13d50719114ee1fa353e89d7d3
 F src/btree.h 32f96abef464cf8765b23ca669acfe90d191fcc5
 F src/build.c 2ed1f14a72ce94a2e4adf333272d67a49925304b
 F src/date.c b3e8b2bef1e3f2ce24e5b057203036defb18c3f1
-F src/delete.c a5191011b7429dff939df631b8bdcc1714b8d7aa
+F src/delete.c 19287dd204569519636a04eca2b66c49c26e9266
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
 F src/expr.c 9ae0e55a230802da35a55fd6e87533cca0301af9
-F src/func.c e520c64e83b4a3fb93668552891124b453cc0eff
+F src/func.c 3d32878eeb4c6a9977c72ec19984d329b6954c7e
 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
-F src/insert.c 1428887f4a7515a7d34e82aaeb76297c79ba378b
+F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18
 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c 96387fc23db30d7ce64f62e95a229c3dd9aff397
+F src/main.c b4cd665e7e0af8f47b523e116e3356d0ebf6cef0
 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
 F src/os.h 1cb5f0293a30288451fe3c0c73815cf208212ed1
 F src/os_common.h ba1b7306e16e2091718f2c48db0fe6c1d7a31bb8
@@ -56,26 +56,26 @@ F src/printf.c 823b6a5cbedb6971a9e62f5d83204fe9b0be7c1b
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 9aa82bbc63983a304bc51d4a7c259e759f92c8dc
 F src/shell.c 24b641700c9d90f361fcfa4f432c5b4aff704e6d
-F src/sqlite.h.in c34414b9f5330f875e26a69fe685e38ca45f11b9
-F src/sqliteInt.h 421687a0b3111d4b3df058aa1a5400739d3d3584
+F src/sqlite.h.in a3d593016d1a1a514d7a26c8a353b58caf62e798
+F src/sqliteInt.h 0d2e3647c0c881826eb07430cd3745c1fee03c27
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
-F src/tclsqlite.c ddef9b18271fb46344d3d35446bd7c001465a69a
+F src/tclsqlite.c 8d093146332b2f0cbf2a8ebe8597d481619308a3
 F src/test1.c ee426e026ad9223483e7a84bb68849fc6e9f542e
 F src/test2.c db0a0c30b59f1639cb8c2572be06439402833cc8
 F src/test3.c 7247090d15a5a43823079b6fd8dad1ed3cccdedf
 F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2
 F src/test5.c 1b7c275b2929dbd034a567255d2aca339410d1d6
 F src/tokenize.c 900374b6b37f04748bcd48c2d29a41c251542935
-F src/trigger.c fb38c34d933f32dbb6c31b48935f33d868cc7658
-F src/update.c f9a03233577e0c3d57234d1957963875fc941da2
+F src/trigger.c 65fa572487f945d3d11ab451f232b430a370bae3
+F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
 F src/utf.c 3a2596013e4b9582d075ca742de7f067ff7dee95
 F src/util.c 1b3743413e11cae51a899dc03fa9b829a3a1f160
 F src/vacuum.c fcb930215a3f6c50087300782555f61ad11dd80c
-F src/vdbe.c 3931b2e4dfb23c8808fb4efc4880dda08c8915ad
-F src/vdbe.h 9ad64674c4c7acd6744174cab5d34013413ef0d3
-F src/vdbeInt.h d007ccada5e3043816097242a560ed6c7f6483ce
+F src/vdbe.c d8e533a537997ddfdf224cc802abaf3aa4448c69
+F src/vdbe.h 05edb8ec5c038e4ea22827350ee75fb20f0dfddf
+F src/vdbeInt.h 4d56da610923efa8d4c9db89dff17cb721e69a9b
 F src/vdbeapi.c 8a9421341e09b506a934132c9015f26362ae8c0e
-F src/vdbeaux.c d2d95f1b9341bd3861e5229cb24a821715824449
+F src/vdbeaux.c fa9f0b179a7df3ce3ef42178ec67ace1c9a68e75
 F src/vdbemem.c 9359c53386e070fea9f5403cab0c6f0cfe36496b
 F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
@@ -93,7 +93,7 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
 F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
 F test/btree7.test 429b96cfef5b51a7d512cfb4b5b3e453384af293
-F test/capi2.test 7a0d71b27cfc5337ec3525c02b9de269b5b9c175
+F test/capi2.test 7ff5ef9efee9f5ad1945e5f80791a7469ae1a040
 F test/capi3.test 6528034f21c4e8e404032124cb58b14ce934598c
 F test/collate1.test 2ee4fa3a47a652ccf56c5ddf65dcc44d9bad82ef
 F test/collate2.test c1a3b41f761b28853c5696037f92de928f93233b
@@ -101,7 +101,7 @@ F test/collate3.test e60b428e07ec945492ba90ff1c895902ee3a8a50
 F test/collate4.test 0e9fc08ffcf6eddf72e354a15de06688fa86db31
 F test/collate5.test 1dd5f0f508c46667f9d4606c7950c414b0bdc0d5
 F test/collate6.test 2a45768914f04c1447a69d1358bbede376552675
-F test/conflict.test 45ce1e44ea748944aed233df8c278a9e1c4c87cc
+F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
 F test/delete.test 4f0c86e2bebdc822d179c80697b1ceabe6bbcd07
@@ -114,14 +114,14 @@ F test/hook.test c4102c672d67f8fb60ea459842805abcba69a747
 F test/in.test b92a2df9162e1cbd33c6449a29a05e6955b1741a
 F test/index.test b6941dd532815f278042b85f79b1a6dc16c4d729
 F test/insert.test ebbab63db4ad69395a058514bccb3cdb0a029d48
-F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f
+F test/insert2.test ea5d4f8dcbc68d8ad85eaa5f03d9812757610f90
 F test/interrupt.test 9142ce4448605127640eda5e283952f75f67ed91
 F test/intpkey.test e6e0d7cca0e64ec09cbf683a4712ed2196073742
 F test/ioerr.test 7d087bfd1a1a53442940e000df936e0df0c5b886
 F test/join.test 9ef6aabaac9de51d5fc41e68d1f4355da05a84cd
 F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
 F test/lastinsert.test 31382f88b9b0270333ac9e4a17f2c2f4732da718
-F test/laststmtchanges.test cabd11bdfbaf73a4486c50b58297d9c2038ccc18
+F test/laststmtchanges.test 417aa27eb2b5cdfafb46e390e2c9ddd0a20eba43
 F test/limit.test 60d7f856ee7846f7130dee67f10f0e726cd70b5d
 F test/lock.test 1dbf1d06b0a7eb36237b4f107cfb3da9726b449e
 F test/main.test e8c4d9ca6d1e5f5e55e6550d31aec488883b2ed9
@@ -153,7 +153,7 @@ F test/sort.test dbd94673b05054e44ca3f08a80faa1e890ef06d8
 F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
 F test/table.test 06c077c82d1a0df45426518064e674d97def6485
 F test/tableapi.test b21ab097e87a5484bb61029e69e1a4e5c5e65ede
-F test/tclsqlite.test a69e99b995c913dde3e554da8b3f8f483715fdd3
+F test/tclsqlite.test 2517b10ee2c806fb700548f54540aec7d62ed14a
 F test/temptable.test 63a16e3ad19adf073cfbcdf7624c92ac5236522c
 F test/tester.tcl f36cc22d0532725073ca78272d7834d56dceb6d9
 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
@@ -225,7 +225,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl af528563442e3039928f9018327a18157e53a44f
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P fc3b3a8fe86980db4de402bb8e85f8f739fc3883
-R 306731b1d3a316b30d565222feb5ad7f
-U dougcurrie
-Z ad297936c1c1ca71d55b605ccce1a407
+P d2ccac9d01994de09a195d71cb63d1bf9fb0d33f
+R 2dec0579dc0c3cd8d98bed6d72c511bb
+U danielk1977
+Z 2ddd8a9b96a59cb5f116b91751ad2717
index a2bd5119cd11885cb67f57350a6f67a26086641d..6f5eb657ced2db1c77f849a45878ad061e009eb2 100644 (file)
@@ -1 +1 @@
-d2ccac9d01994de09a195d71cb63d1bf9fb0d33f
\ No newline at end of file
+ae2f4a0943854fedbbb6fab1dc3aaf972722ed95
\ No newline at end of file
index 868bbd2ac8870e13d2ac77a56b11c6da64c05c1f..ec105cbf35ac3664cf41c48d85dfbf00219ca567 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.75 2004/06/17 07:53:02 danielk1977 Exp $
+** $Id: delete.c,v 1.76 2004/06/21 06:50:27 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -142,6 +142,7 @@ void sqlite3DeleteFrom(
   if( v==0 ){
     goto delete_from_cleanup;
   }
+  sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
 
   /* If we are trying to delete from a view, construct that view into
@@ -271,7 +272,7 @@ void sqlite3DeleteFrom(
       }
 
       /* Delete the row */
-      sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->trigStack==0);
+      sqlite3GenerateRowDelete(db, v, pTab, iCur, 1);
     }
 
     /* If there are row triggers, close all cursors then invoke
@@ -303,7 +304,6 @@ void sqlite3DeleteFrom(
       pParse->nTab = iCur;
     }
   }
-  sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
   sqlite3EndWriteOperation(pParse);
 
   /*
@@ -352,8 +352,7 @@ void sqlite3GenerateRowDelete(
   int addr;
   addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
   sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
-  sqlite3VdbeAddOp(v, OP_Delete, iCur,
-    (count?OPFLAG_NCHANGE:0) | OPFLAG_CSCHANGE);
+  sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
   sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
 }
 
index 5b5f882fced21bd995ba81d067fff02a275630df..6c22ece385f3c5e1c13f094bd9cfbde833409004 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.74 2004/06/19 17:33:07 drh Exp $
+** $Id: func.c,v 1.75 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #include <ctype.h>
 #include <math.h>
@@ -273,10 +273,10 @@ static void last_insert_rowid(
 }
 
 /*
-** Implementation of the change_count() SQL function.  The return
-** value is the same as the sqlite3_changes() API function.
+** Implementation of the changes() SQL function.  The return value is the
+** same as the sqlite3_changes() API function.
 */
-static void change_count(
+static void changes(
   sqlite3_context *context,
   int arg,
   sqlite3_value **argv
@@ -286,19 +286,20 @@ static void change_count(
 }
 
 /*
-** Implementation of the last_statement_change_count() SQL function.  The
-** return value is the same as the sqlite3_last_statement_changes() API
-** function.
+** Implementation of the total_changes() SQL function.  The return value is
+** the same as the sqlite3_total_changes() API function.
 */
-static void last_statement_change_count(
-  sqlite3_context *context, 
+static void total_changes(
+  sqlite3_context *context,
   int arg,
   sqlite3_value **argv
 ){
   sqlite *db = sqlite3_user_data(context);
-  sqlite3_result_int(context, sqlite3_last_statement_changes(db));
+  sqlite3_result_int(context, sqlite3_total_changes(db));
 }
 
+#if 0
+
 /*
 ** A LIKE pattern compiles to an instance of the following structure. Refer
 ** to the comment for compileLike() function for details.
@@ -315,9 +316,6 @@ typedef struct LikePattern LikePattern;
 void deleteLike(void *pLike){
   sqliteFree(pLike);
 }
-
-
-#if 0
 /* #define TRACE_LIKE */
 #if defined(TRACE_LIKE) && !defined(NDEBUG)
 char *dumpLike(LikePattern *pLike){
@@ -1041,9 +1039,8 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){
     { "sqlite_version",              0, 0, SQLITE_UTF8, 0, versionFunc},
     { "quote",                       1, 0, SQLITE_UTF8, 0, quoteFunc  },
     { "last_insert_rowid",           0, 1, SQLITE_UTF8, 0, last_insert_rowid },
-    { "change_count",                0, 1, SQLITE_UTF8, 0, change_count      },
-    { "last_statement_change_count", 0, 1, SQLITE_UTF8, 0, 
-       last_statement_change_count },
+    { "changes",                     0, 1, SQLITE_UTF8, 0, changes    },
+    { "total_changes",               0, 1, SQLITE_UTF8, 0, total_changes },
 #ifdef SQLITE_SOUNDEX
     { "soundex",                     1, 0, SQLITE_UTF8, 0, soundexFunc},
 #endif
index ef4f03d7cc032defb9b83964ede6a0150bebb56d..7a79df20e1f7c3a7a770c25630ac258dbea97cc9 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.112 2004/06/17 07:53:03 danielk1977 Exp $
+** $Id: insert.c,v 1.113 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -245,6 +245,7 @@ void sqlite3Insert(
   */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto insert_cleanup;
+  sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
 
   /* if there are row triggers, allocate a temp table for new.* references. */
@@ -617,7 +618,6 @@ void sqlite3Insert(
     }
   }
 
-  sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
   sqlite3EndWriteOperation(pParse);
 
   /*
@@ -967,6 +967,7 @@ void sqlite3CompleteInsertion(
   Vdbe *v;
   int nIdx;
   Index *pIdx;
+  int pik_flags;
 
   v = sqlite3GetVdbe(pParse);
   assert( v!=0 );
@@ -983,9 +984,9 @@ void sqlite3CompleteInsertion(
     sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
     sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
   }
-  sqlite3VdbeAddOp(v, OP_PutIntKey, base,
-    (pParse->trigStack?0:OPFLAG_NCHANGE) |
-    (isUpdate?0:OPFLAG_LASTROWID) | OPFLAG_CSCHANGE);
+  pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
+  sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);
+  
   if( isUpdate && recnoChng ){
     sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
   }
index 2c23bda562f59ae4f0505c5dd150745d45d89d9d..b132d0b93c170c95991b89800b107d2534a3ecaa 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.230 2004/06/19 09:35:37 danielk1977 Exp $
+** $Id: main.c,v 1.231 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -448,13 +448,10 @@ int sqlite3_changes(sqlite *db){
 }
 
 /*
-** Return the number of changes produced by the last INSERT, UPDATE, or
-** DELETE statement to complete execution. The count does not include
-** changes due to SQL statements executed in trigger programs that were
-** triggered by that statement
+** Return the number of changes since the database handle was opened.
 */
-int sqlite3_last_statement_changes(sqlite *db){
-  return db->lsChange;
+int sqlite3_total_changes(sqlite3 *db){
+  return db->nTotalChange;
 }
 
 /*
@@ -952,7 +949,6 @@ int sqlite3_prepare(
     goto prepare_out;
   }
 
-  if( db->pVdbe==0 ){ db->nChange = 0; }
   memset(&sParse, 0, sizeof(sParse));
   sParse.db = db;
   sqlite3RunParser(&sParse, zSql, &zErrMsg);
index 29f6d487844983f1be14f93a93a32cb6c2ee1928..aba3017b6b976736a7c80756856c205d6ba65e33 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.104 2004/06/19 08:18:16 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.105 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #ifndef _SQLITE_H_
 #define _SQLITE_H_
@@ -176,20 +176,34 @@ long long int sqlite3_last_insert_rowid(sqlite3*);
 */
 int sqlite3_changes(sqlite3*);
 
+/*
+** This function returns the number of database rows that have been
+** modified by INSERT, UPDATE or DELETE statements since the database handle
+** was opened. This includes UPDATE, INSERT and DELETE statements executed
+** as part of trigger programs. All changes are counted as soon as the
+** statement that makes them is completed (when the statement handle is
+** passed to sqlite3_reset() or sqlite_finalise()).
+**
+** 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 sqlite3_total_changes(sqlite3*);
+
 /*
 ** This function returns the number of database rows that were changed
-** by the last INSERT, UPDATE, or DELETE statment executed by sqlite3_exec(),
-** or by the last VM to run to completion. The change count is not updated
-** by SQL statements other than INSERT, UPDATE or DELETE.
+** by the last INSERT, UPDATE, or DELETE statment completed.  The change
+** count is not updated by SQL statements other than INSERT, UPDATE or
+** DELETE.
 **
 ** Changes are counted, even if they are later undone by a ROLLBACK or
 ** ABORT. Changes associated with trigger programs that execute as a
 ** result of the INSERT, UPDATE, or DELETE statement are not counted.
 **
-** If a callback invokes sqlite3_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
@@ -197,10 +211,8 @@ int sqlite3_changes(sqlite3*);
 ** 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.
-**
-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
 */
-int sqlite3_last_statement_changes(sqlite3*);
+int sqlite3_changes(sqlite3*);
 
 /* This function causes any pending database operation to abort and
 ** return at its earliest opportunity.  This routine is typically
index c8531ab90081c72e457acd87889aa37540047d04..d7aa7ba634c3d600551e6bc728f9b0361b3319e2 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.295 2004/06/19 16:06:12 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.296 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #include "config.h"
 #include "sqlite3.h"
@@ -318,16 +318,6 @@ struct Db {
 #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
 #define DB_UnresetViews    0x0002  /* Some views have defined column names */
 
-#if 0
-/*
-** Possible values for the Db.textEnc field.
-*/
-#define TEXT_Utf8          1
-#define TEXT_Utf16le       2
-#define TEXT_Utf16be       3
-#define TEXT_Utf16         (SQLITE_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le)
-#endif
-
 #define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
 
 /*
@@ -394,13 +384,12 @@ struct sqlite {
   i64 lastRowid;                /* ROWID of most recent insert (see above) */
   i64 priorNewRowid;            /* Last randomly generated ROWID */
   int magic;                    /* Magic number for detect library misuse */
-  int nChange;                  /* Number of rows changed (see above) */
-  int lsChange;                 /* Last statement change count (see above) */
-  int csChange;                 /* Current statement change count (see above) */
-  struct sqlite3InitInfo {       /* Information used during initialization */
-    int iDb;                       /* When back is being initialized */
-    int newTnum;                   /* Rootpage of table being initialized */
-    u8 busy;                       /* TRUE if currently initializing */
+  int nChange;                  /* Value returned by sqlite3_changes() */
+  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
+  struct sqlite3InitInfo {      /* Information used during initialization */
+    int iDb;                    /* When back is being initialized */
+    int newTnum;                /* Rootpage of table being initialized */
+    u8 busy;                    /* TRUE if currently initializing */
   } init;
   struct Vdbe *pVdbe;           /* List of active virtual machines */
   int activeVdbeCnt;            /* Number of vdbes currently executing */
@@ -1050,7 +1039,6 @@ struct AuthContext {
 */
 #define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
 #define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
-#define OPFLAG_CSCHANGE  4    /* Set to update db->csChange */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
@@ -1402,6 +1390,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
 int sqlite3CheckCollSeq(Parse *, CollSeq *);
 int sqlite3CheckIndexCollSeq(Parse *, Index *);
 int sqlite3CheckObjectName(Parse *, const char *);
+void sqlite3VdbeSetChanges(sqlite3 *, int);
 
 const void *sqlite3ValueText(sqlite3_value*, u8);
 int sqlite3ValueBytes(sqlite3_value*, u8);
index 5c033ee1f037f5147e5207b0f82de814dc0cc690..361aa59db45f865bb057f937b9f9a6c3f228322e 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.89 2004/06/19 08:18:21 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.90 2004/06/21 06:50:28 danielk1977 Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -69,7 +69,6 @@ struct SqliteDb {
   SqlFunc *pFunc;       /* List of SQL functions */
   SqlCollate *pCollate; /* List of SQL collation functions */
   int rc;               /* Return code of most recent sqlite3_exec() */
-  int nChange;          /* Database changes for the most recent eval */
   Tcl_Obj *pCollateNeeded;  /* Collation needed script */
 };
 
@@ -395,18 +394,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     "authorizer",         "busy",                   "changes",
     "close",              "commit_hook",            "complete",
     "errorcode",          "eval",                   "function",
-    "last_insert_rowid",  "last_statement_changes", "onecolumn",
+    "last_insert_rowid",  "onecolumn",
     "progress",           "rekey",                  "timeout",
     "trace",              "collate",                "collation_needed",
-    0                    
+    "total_changes",      0                    
   };
   enum DB_enum {
     DB_AUTHORIZER,        DB_BUSY,                   DB_CHANGES,
     DB_CLOSE,             DB_COMMIT_HOOK,            DB_COMPLETE,
     DB_ERRORCODE,         DB_EVAL,                   DB_FUNCTION,
-    DB_LAST_INSERT_ROWID, DB_LAST_STATEMENT_CHANGES, DB_ONECOLUMN,        
+    DB_LAST_INSERT_ROWID, DB_ONECOLUMN,        
     DB_PROGRESS,          DB_REKEY,                  DB_TIMEOUT,
-    DB_TRACE,             DB_COLLATE,                DB_COLLATION_NEEDED
+    DB_TRACE,             DB_COLLATE,                DB_COLLATION_NEEDED,
+    DB_TOTAL_CHANGES
   };
 
   if( objc<2 ){
@@ -547,43 +547,20 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     break;
   }
 
-  /*
-  **     $db changes
+  /*     $db changes
   **
   ** Return the number of rows that were modified, inserted, or deleted by
-  ** the most recent "eval".
+  ** the most recent INSERT, UPDATE or DELETE statement, not including 
+  ** any changes made by trigger programs.
   */
   case DB_CHANGES: {
     Tcl_Obj *pResult;
-    int nChange;
-    if( objc!=2 ){
-      Tcl_WrongNumArgs(interp, 2, objv, "");
-      return TCL_ERROR;
-    }
-    /* nChange = sqlite3_changes(pDb->db); */
-    nChange = pDb->nChange;
-    pResult = Tcl_GetObjResult(interp);
-    Tcl_SetIntObj(pResult, nChange);
-    break;
-  }
-
-  /*
-  **     $db last_statement_changes
-  **
-  ** Return the number of rows that were modified, inserted, or deleted by
-  ** the last statment to complete execution (excluding changes due to
-  ** triggers)
-  */
-  case DB_LAST_STATEMENT_CHANGES: {
-    Tcl_Obj *pResult;
-    int lsChange;
     if( objc!=2 ){
       Tcl_WrongNumArgs(interp, 2, objv, "");
       return TCL_ERROR;
     }
-    lsChange = sqlite3_last_statement_changes(pDb->db);
     pResult = Tcl_GetObjResult(interp);
-    Tcl_SetIntObj(pResult, lsChange);
+    Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
     break;
   }
 
@@ -685,7 +662,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       return TCL_ERROR;
     }
 
-    pDb->nChange = 0;
     zSql = Tcl_GetStringFromObj(objv[2], 0);
     while( zSql[0] ){
       int i;
@@ -750,7 +726,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
         break;
       }
 
-      pDb->nChange += sqlite3_changes(pDb->db);
       zSql = zLeft;
     }
 
@@ -960,6 +935,23 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     break;
   }
 
+  /*
+  **     $db total_changes
+  **
+  ** Return the number of rows that were modified, inserted, or deleted 
+  ** since the database handle was created.
+  */
+  case DB_TOTAL_CHANGES: {
+    Tcl_Obj *pResult;
+    if( objc!=2 ){
+      Tcl_WrongNumArgs(interp, 2, objv, "");
+      return TCL_ERROR;
+    }
+    pResult = Tcl_GetObjResult(interp);
+    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
+    break;
+  }
+
   } /* End of the SWITCH statement */
   return rc;
 }
index 23c43b764d027ade6d8fb56bf66169d41fe8449c..19fd50ddd4173bdf0d116fa762e83196d917e9c2 100644 (file)
@@ -650,28 +650,34 @@ static int codeTriggerProgram(
       case TK_UPDATE: {
         SrcList *pSrc;
         pSrc = targetSrcList(pParse, pTriggerStep);
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
         sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
         sqlite3Update(pParse, pSrc,
                sqlite3ExprListDup(pTriggerStep->pExprList), 
                sqlite3ExprDup(pTriggerStep->pWhere), orconf);
         sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
         break;
       }
       case TK_INSERT: {
         SrcList *pSrc;
         pSrc = targetSrcList(pParse, pTriggerStep);
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
         sqlite3Insert(pParse, pSrc,
           sqlite3ExprListDup(pTriggerStep->pExprList), 
           sqlite3SelectDup(pTriggerStep->pSelect), 
           sqlite3IdListDup(pTriggerStep->pIdList), orconf);
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
         break;
       }
       case TK_DELETE: {
         SrcList *pSrc;
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
         sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
         pSrc = targetSrcList(pParse, pTriggerStep);
         sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
         sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
+        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
         break;
       }
       default:
index eae9dab4db0822f4dc1aad9a6f7194ab2e53f3f8..59a373aab604e347903ced7989baaf9dc5ac1f6e 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.84 2004/06/16 12:02:52 danielk1977 Exp $
+** $Id: update.c,v 1.85 2004/06/21 06:50:29 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -209,6 +209,7 @@ void sqlite3Update(
   */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto update_cleanup;
+  sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
 
   /* If we are trying to update a view, construct that view into
@@ -440,7 +441,6 @@ void sqlite3Update(
     sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
   }
 
-  sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
   sqlite3EndWriteOperation(pParse);
 
   /*
index f821f4f650096f417cb546f9d1ff2d71bd7f1a2e..68661340dd3668fd594f542012b77b840705c2b1 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.381 2004/06/19 15:40:23 drh Exp $
+** $Id: vdbe.c,v 1.382 2004/06/21 06:50:29 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -3066,11 +3066,9 @@ case OP_NewRecno: {
 ** be an integer.  The stack is popped twice by this instruction.
 **
 ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-** incremented (otherwise not).  If the OPFLAG_CSCHANGE flag is set,
-** then the current statement change count is incremented (otherwise not).
-** If the OPFLAG_LASTROWID flag of P2 is set, then rowid is
-** stored for subsequent return by the sqlite3_last_insert_rowid() function
-** (otherwise it's unmodified).
+** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
+** then rowid is stored for subsequent return by the
+** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
 */
 /* Opcode: PutStrKey P1 * *
 **
@@ -3115,9 +3113,8 @@ case OP_PutStrKey: {
         zKey = (char*)&iKey;
       }
 
-      if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
+      if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
       if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
-      if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
       if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
         pC->nextRowidValid = 0;
       }
@@ -3169,8 +3166,7 @@ case OP_PutStrKey: {
 ** a record from within an Next loop.
 **
 ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-** incremented (otherwise not).  If OPFLAG_CSCHANGE flag is set,
-** then the current statement change count is incremented (otherwise not).
+** incremented (otherwise not).
 **
 ** If P1 is a pseudo-table, then this instruction is a no-op.
 */
@@ -3186,19 +3182,22 @@ case OP_Delete: {
     pC->nextRowidValid = 0;
     pC->cacheValid = 0;
   }
-  if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
-  if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
+  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
   break;
 }
 
-/* Opcode: SetCounts * * *
+/* Opcode: ResetCount P1 * *
 **
-** Called at end of statement.  Updates lsChange (last statement change count)
-** and resets csChange (current statement change count) to 0.
+** This opcode resets the VMs internal change counter to 0. If P1 is true,
+** then the value of the change counter is copied to the database handle
+** change counter (returned by subsequent calls to sqlite3_changes())
+** before it is reset. This is used by trigger programs.
 */
-case OP_SetCounts: {
-  db->lsChange=db->csChange;
-  db->csChange=0;
+case OP_ResetCount: {
+  if( pOp->p1 ){
+    sqlite3VdbeSetChanges(p->db, p->nChange);
+  }
+  p->nChange = 0;
   break;
 }
 
@@ -3994,9 +3993,12 @@ case OP_ListReset: {
 case OP_ListPush: {
   p->keylistStackDepth++;
   assert(p->keylistStackDepth > 0);
+
+  /* FIX ME: This should be allocated at compile time. */
   p->keylistStack = sqliteRealloc(p->keylistStack, 
           sizeof(Keylist *) * p->keylistStackDepth);
   if( p->keylistStack==0 ) goto no_mem;
+
   p->keylistStack[p->keylistStackDepth - 1] = p->pList;
   p->pList = 0;
   break;
@@ -4028,13 +4030,20 @@ case OP_ListPop: {
 */
 case OP_ContextPush: {
   p->contextStackDepth++;
-  assert(p->contextStackDepth > 0);
+  assert( p->contextStackDepth>0 );
+
+  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
   p->contextStack = sqliteRealloc(p->contextStack, 
           sizeof(Context) * p->contextStackDepth);
   if( p->contextStack==0 ) goto no_mem;
+
   p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid;
+  p->contextStack[p->contextStackDepth - 1].nChange = p->nChange;
+
+#if 0
   p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
   p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
+#endif
   break;
 }
 
@@ -4048,8 +4057,11 @@ case OP_ContextPop: {
   assert(p->contextStackDepth > 0);
   p->contextStackDepth--;
   p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid;
+  p->nChange = p->contextStack[p->contextStackDepth].nChange;
+#if 0
   p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange;
   p->db->csChange = p->contextStack[p->contextStackDepth].csChange;
+#endif
   if( p->contextStackDepth == 0 ){
     sqliteFree(p->contextStack);
     p->contextStack = 0;
index 6abe89a6e236ba258ac7eedc1ee6f419a6a78911..a66bef1df6aa123b23305b10eed5b65217f44ba0 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.86 2004/06/19 14:49:12 drh Exp $
+** $Id: vdbe.h,v 1.87 2004/06/21 06:50:29 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -123,6 +123,7 @@ int sqlite3VdbeReset(Vdbe*,char **);
 int sqliteVdbeSetVariables(Vdbe*,int,const char**);
 void sqlite3VdbeSetNumCols(Vdbe*,int);
 int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
+void sqlite3VdbeCountChanges(Vdbe*);
 
 #ifndef NDEBUG
   void sqlite3VdbeComment(Vdbe*, const char*, ...);
index 02fa033c71223d3ac6148089baa7d0501d5f8291..5e71fdf7786376cf29f44a5062f8df42b53187b8 100644 (file)
@@ -287,9 +287,8 @@ struct Keylist {
 */
 typedef struct Context Context;
 struct Context {
-  int lastRowid;    /* Last insert rowid (from db->lastRowid) */
-  int lsChange;     /* Last statement change count (from db->lsChange) */
-  int csChange;     /* Current statement change count (from db->csChange) */
+  int lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
+  int nChange;      /* Statement changes (Vdbe.nChanges)     */
 };
 
 /*
@@ -347,6 +346,8 @@ struct Vdbe {
   u8 resOnStack;          /* True if there are result values on the stack */
   u8 explain;             /* True if EXPLAIN present on SQL command */
   u8 autoCommitOn;        /* True if autocommit got turned on by this program */
+  int nChange;            /* Number of db changes made since last reset */
+  u8 changeCntOn;         /* True to update the change-counter */
 };
 
 /*
index 4a7da7b51caadc66e8d845803ab5b8d227ad4b56..24457907218f5082cfa25591fc421f6491d057aa 100644 (file)
@@ -645,6 +645,7 @@ void sqlite3VdbeMakeReady(
   p->popStack =  0;
   p->explain |= isExplain;
   p->magic = VDBE_MAGIC_RUN;
+  p->nChange = 0;
 #ifdef VDBE_PROFILE
   {
     int i;
@@ -1247,6 +1248,15 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
     }
   }
 
+  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
+  if( p->changeCntOn ){
+    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
+      sqlite3VdbeSetChanges(db, p->nChange);
+    }else{
+      sqlite3VdbeSetChanges(db, 0);
+    }
+    p->nChange = 0;
+  }
 
   if( p->rc!=SQLITE_OK ){
     sqlite3RollbackInternalChanges(db);
@@ -1355,7 +1365,6 @@ void sqlite3VdbeDelete(Vdbe *p){
       sqliteFree(pOp->p3);
     }
     if( pOp->p3type==P3_VDBEFUNC ){
-      int j;
       VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
       sqlite3VdbeDeleteAuxData(pVdbeFunc, -1);
       sqliteFree(pVdbeFunc);
@@ -1755,3 +1764,23 @@ int sqlite3VdbeIdxKeyCompare(
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
 }
+
+/*
+** This routine sets the value to be returned by subsequent calls to
+** sqlite3_changes() on the database handle 'db'. 
+*/
+void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
+  db->nChange = nChange;
+  db->nTotalChange += nChange;
+}
+
+/*
+** Set a flag in the vdbe to update the change counter when it is finalised
+** or reset.
+*/
+void sqlite3VdbeCountChanges(Vdbe *p){
+  p->changeCntOn = 1;
+}
+
+
+
index 4f40174467faac56d1fac030fe8ee31bc79149a1..7c1e65d6b06336d3e93054c7e5f859fc7765922f 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script testing the callback-free C/C++ API.
 #
-# $Id: capi2.test,v 1.14 2004/06/19 00:16:31 drh Exp $
+# $Id: capi2.test,v 1.15 2004/06/21 06:50:29 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -227,11 +227,11 @@ do_test capi2-3.10 {
 
 # Update for v3 - the change has not actually happened until the query is
 # finalized. Is this going to cause trouble for anyone? Lee Nelson maybe?
-do_test capi2-3.10b {sqlite3_changes $DB} {1}
+do_test capi2-3.10b {db changes} {0}
 do_test capi2-3.11 {
   sqlite3_finalize $VM
 } {SQLITE_OK}
-do_test capi2-3.11b {sqlite3_changes $DB} {1}
+do_test capi2-3.11b {db changes} {1}
 do_test capi2-3.12 {
   sqlite3_finalize $VM
 } {SQLITE_MISUSE}
@@ -242,7 +242,11 @@ do_test capi2-3.13 {
        [get_row_values $VM] \
        [get_column_names $VM]
 } {SQLITE_ERROR 0 {} {}}
-do_test capi2-3.13b {db changes} {0}
+
+# Update for v3: Preparing a statement does not affect the change counter.
+# (Test result changes from 0 to 1).
+do_test capi2-3.13b {db changes} {1}
+
 do_test capi2-3.14 {
   list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
 } {SQLITE_CONSTRAINT {column a is not unique}}
@@ -602,9 +606,16 @@ do_test capi2-7.10 {
     SELECT * FROM t1;
   }
 } {0 4 1 2 3 2 3 4 3 4 5 4 5 6}
+
+# Update for version 3: A SELECT statement no longer resets the change
+# counter (Test result changes from 0 to 4).
 do_test capi2-7.11 {
   sqlite3_changes $DB
-} {0}
+} {4}
+do_test capi2-7.11a {
+  execsql {SELECT count(*) FROM t1}
+} {4}
+
 do_test capi2-7.12 {
   set x [stepsql $DB {EXPLAIN SELECT * FROM t1}]
   lindex $x 0
index 89ba507e55b7169ce849215119945edb450ae24a..1369b773a6296067354ba95ff013c1ae28852e14 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the conflict resolution extension
 # to SQLite.
 #
-# $Id: conflict.test,v 1.21 2004/05/31 08:55:34 danielk1977 Exp $
+# $Id: conflict.test,v 1.22 2004/06/21 06:50:29 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -383,9 +383,12 @@ do_test conflict-7.7 {
     SELECT count(*) FROM t1;
   }
 } {1}
+
+# Update for version 3: A SELECT statement no longer resets the change
+# counter (Test result changes from 0 to 50).
 do_test conflict-7.7.1 {
   db changes
-} {0}
+} {50}
 
 # Make sure the row count is right for rows that are ignored on
 # an insert.
index 8c30cb0ec9a597c4dc600032e940676c8167fc07..0cd292f279ff416be1a369c24c3f30c9752be470 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing the INSERT statement that takes is
 # result from a SELECT.
 #
-# $Id: insert2.test,v 1.10 2002/06/25 13:16:04 drh Exp $
+# $Id: insert2.test,v 1.11 2004/06/21 06:50:29 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -125,6 +125,7 @@ do_test insert2-3.1 {
   }
 } {1 2}
 do_test insert2-3.2 {
+  set x [db total_changes]
   execsql {
     BEGIN;
     INSERT INTO t4 VALUES(2,4);
@@ -138,7 +139,7 @@ do_test insert2-3.2 {
     INSERT INTO t4 VALUES(10,20);
     COMMIT;
   }
-  db changes
+  expr [db total_changes] - $x
 } {9}
 do_test insert2-3.2.1 {
   execsql {
index b7929847be639b6ab65eb8a69968df1640c1b7ed..f7adcd2e7998db880cb736e2ffb59d41fee97a0b 100644 (file)
@@ -7,16 +7,17 @@
 #
 #***********************************************************************
 #
-# Tests to make sure that value returned by last_statement_change_count()
-# (LSCC) is updated properly, especially inside triggers
+# Tests to make sure that values returned by changes() and total_changes()
+# are updated properly, especially inside triggers
 #
-# Note 1: LSCC remains constant within a statement and only updates once
-#           the statement is finished (triggers count as part of statement)
-# Note 2: LSCC is changed within the context of a trigger
-#           much like last_insert_rowid() (see lastinsert.test),
-#           but is restored once the trigger exits
-# Note 3: LSCC is not changed by a change to a view (since everything
-#           is done within instead of trigger context)
+# Note 1: changes() remains constant within a statement and only updates
+#         once the statement is finished (triggers count as part of
+#         statement).
+# Note 2: changes() is changed within the context of a trigger much like 
+#         last_insert_rowid() (see lastinsert.test), but is restored once
+#         the trigger exits.
+# Note 3: changes() is not changed by a change to a view (since everything
+#         is done within instead of trigger context).
 #
 
 set testdir [file dirname $argv0]
@@ -25,7 +26,7 @@ source $testdir/tester.tcl
 # ----------------------------------------------------------------------------
 # 1.x - basic tests (no triggers)
 
-# LSCC set properly after insert
+# changes() set properly after insert
 do_test laststmtchanges-1.1 {
     catchsql {
         create table t0 (x);
@@ -37,100 +38,112 @@ do_test laststmtchanges-1.1 {
         insert into t0 values (1);
         insert into t0 values (1);
         insert into t0 values (2);
-        select last_statement_change_count();
+        select changes(), total_changes();
     }
-} {0 1}
+} {0 {1 8}}
 
-# LSCC set properly after update
+# changes() set properly after update
 do_test laststmtchanges-1.2 {
     catchsql {
         update t0 set x=3 where x=1;
-        select last_statement_change_count();
+        select changes(), total_changes();
     }
-} {0 5}
+} {0 {5 13}}
 
-# LSCC unchanged within an update statement
+# changes() unchanged within an update statement
 do_test laststmtchanges-1.3 {
     catchsql {
-        update t0 set x=x+last_statement_change_count() where x=3;
+        update t0 set x=x+changes() where x=3;
         select count() from t0 where x=8;
     }
 } {0 5}
 
-# LSCC set properly after update on table where no rows changed
+# changes() set properly after update on table where no rows changed
 do_test laststmtchanges-1.4 {
     catchsql {
         update t0 set x=77 where x=88;
-        select last_statement_change_count();
+        select changes();
     }
 } {0 0}
 
-# LSCC set properly after delete from table
+# changes() set properly after delete from table
 do_test laststmtchanges-1.5 {
     catchsql {
         delete from t0 where x=2;
-        select last_statement_change_count();
+        select changes();
     }
 } {0 3}
 
 # ----------------------------------------------------------------------------
 # 2.x - tests with after insert trigger
 
-# LSCC changed properly after insert into table containing after trigger
+# changes() changed properly after insert into table containing after trigger
 do_test laststmtchanges-2.1 {
+    set ::tc [db total_changes]
     catchsql {
         create table t1 (k integer primary key);
         create table t2 (k integer primary key, v1, v2);
         create trigger r1 after insert on t1 for each row begin
-            insert into t2 values (NULL, last_statement_change_count(), NULL);
+            insert into t2 values (NULL, changes(), NULL);
             update t0 set x=x;
-            update t2 set v2=last_statement_change_count();
+            update t2 set v2=changes();
         end;
         insert into t1 values (77);
-        select last_statement_change_count();
+        select changes();
     }
 } {0 1}
 
-# LSCC unchanged upon entry into after insert trigger
+# changes() unchanged upon entry into after insert trigger
 do_test laststmtchanges-2.2 {
     catchsql {
         select v1 from t2;
     }
 } {0 3}
 
-# LSCC changed properly by update within context of after insert trigger
+# changes() changed properly by update within context of after insert trigger
 do_test laststmtchanges-2.3 {
     catchsql {
         select v2 from t2;
     }
 } {0 5}
 
+# Total changes caused by firing the trigger above:
+#
+#   1 from "insert into t1 values(77)" + 
+#   1 from "insert into t2 values (NULL, changes(), NULL);" +
+#   5 from "update t0 set x=x;" +
+#   1 from "update t2 set v2=changes();"
+#
+do_test laststmtchanges-2.4 {
+  expr [db total_changes] - $::tc
+} {8}
+
 # ----------------------------------------------------------------------------
 # 3.x - tests with after update trigger
 
-# LSCC changed properly after update into table containing after trigger
+# changes() changed properly after update into table containing after trigger
 do_test laststmtchanges-3.1 {
     catchsql {
         drop trigger r1;
         delete from t2; delete from t2;
         create trigger r1 after update on t1 for each row begin
-            insert into t2 values (NULL, last_statement_change_count(), NULL);
+            insert into t2 values (NULL, changes(), NULL);
             delete from t0 where oid=1 or oid=2;
-            update t2 set v2=last_statement_change_count();
+            update t2 set v2=changes();
         end;
         update t1 set k=k;
-        select last_statement_change_count();
+        select changes();
     }
 } {0 1}
 
-# LSCC unchanged upon entry into after update trigger
+# changes() unchanged upon entry into after update trigger
 do_test laststmtchanges-3.2 {
     catchsql {
         select v1 from t2;
     }
 } {0 0}
 
-# LSCC changed properly by delete within context of after update trigger
+# changes() changed properly by delete within context of after update trigger
 do_test laststmtchanges-3.3 {
     catchsql {
         select v2 from t2;
@@ -140,29 +153,29 @@ do_test laststmtchanges-3.3 {
 # ----------------------------------------------------------------------------
 # 4.x - tests with before delete trigger
 
-# LSCC changed properly on delete from table containing before trigger
+# changes() changed properly on delete from table containing before trigger
 do_test laststmtchanges-4.1 {
     catchsql {
         drop trigger r1;
         delete from t2; delete from t2;
         create trigger r1 before delete on t1 for each row begin
-            insert into t2 values (NULL, last_statement_change_count(), NULL);
+            insert into t2 values (NULL, changes(), NULL);
             insert into t0 values (5);
-            update t2 set v2=last_statement_change_count();
+            update t2 set v2=changes();
         end;
         delete from t1;
-        select last_statement_change_count();
+        select changes();
     }
 } {0 1}
 
-# LSCC unchanged upon entry into before delete trigger
+# changes() unchanged upon entry into before delete trigger
 do_test laststmtchanges-4.2 {
     catchsql {
         select v1 from t2;
     }
 } {0 0}
 
-# LSCC changed properly by insert within context of before delete trigger
+# changes() changed properly by insert within context of before delete trigger
 do_test laststmtchanges-4.3 {
     catchsql {
         select v2 from t2;
@@ -191,40 +204,40 @@ do_test laststmtchanges-5.1 {
         insert into t0 values (2);
         insert into t0 values (1);
         create temp trigger r1 instead of insert on v1 for each row begin
-            insert into n1 values (NULL, last_statement_change_count());
+            insert into n1 values (NULL, changes());
             update t0 set x=x*10 where x=1;
-            insert into n1 values (NULL, last_statement_change_count());
+            insert into n1 values (NULL, changes());
             insert into t1 values (NEW.k);
-            insert into n1 values (NULL, last_statement_change_count());
+            insert into n1 values (NULL, changes());
             update t0 set x=x*10 where x=0;
             insert into v2 values (100+NEW.k);
-            insert into n1 values (NULL, last_statement_change_count());
+            insert into n1 values (NULL, changes());
         end;
         create temp trigger r2 instead of insert on v2 for each row begin
-            insert into n2 values (NULL, last_statement_change_count());
+            insert into n2 values (NULL, changes());
             insert into t2 values (1000+NEW.k);
-            insert into n2 values (NULL, last_statement_change_count());
+            insert into n2 values (NULL, changes());
             update t0 set x=x*100 where x=0;
-            insert into n2 values (NULL, last_statement_change_count());
+            insert into n2 values (NULL, changes());
             delete from t0 where x=2;
-            insert into n2 values (NULL, last_statement_change_count());
+            insert into n2 values (NULL, changes());
         end;
         insert into t1 values (77);
-        select last_statement_change_count();
+        select changes();
     }
 } {0 1}
 
 do_test laststmtchanges-5.2 {
     catchsql {
         delete from t1 where k=88;
-        select last_statement_change_count();
+        select changes();
     }
 } {0 0}
 
 do_test laststmtchanges-5.3 {
     catchsql {
         insert into v1 values (5);
-        select last_statement_change_count();
+        select changes();
     }
 } {0 0}
 
index 2920d97d0dffe670cf3f3a0a7a02e78513849e9e..8533a256a9e72d62f144950b1471fac93436bb19 100644 (file)
@@ -15,7 +15,7 @@
 # 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.24 2004/06/19 00:16:31 drh Exp $
+# $Id: tclsqlite.test,v 1.25 2004/06/21 06:50:29 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -34,7 +34,7 @@ do_test tcl-1.1 {
 do_test tcl-1.2 {
   set v [catch {db bogus} msg]
   lappend v $msg
-} {1 {bad option "bogus": must be authorizer, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, last_statement_changes, onecolumn, progress, rekey, timeout, trace, collate, or collation_needed}}
+} {1 {bad option "bogus": must be authorizer, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, onecolumn, progress, rekey, timeout, trace, collate, collation_needed, or total_changes}}
 do_test tcl-1.3 {
   execsql {CREATE TABLE t1(a int, b int)}
   execsql {INSERT INTO t1 VALUES(10,20)}