]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update comments in sqlite3session.h. More to come.
authordan <dan@noemail.net>
Fri, 18 Mar 2011 13:05:15 +0000 (13:05 +0000)
committerdan <dan@noemail.net>
Fri, 18 Mar 2011 13:05:15 +0000 (13:05 +0000)
FossilOrigin-Name: e73e9082f3b14088752717193a10dd7657deb8af

ext/session/sqlite3session.h
install-sh [changed mode: 0755->0644]
manifest
manifest.uuid
test/progress.test [changed mode: 0644->0755]
tool/mkopts.tcl [changed mode: 0644->0755]

index 573b2ff3fc750fe3191db41737d46da4206919f1..9cf7cda488d693fee55b6290daf64b8fee8b09b1 100644 (file)
@@ -18,7 +18,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
 ** Create a new session object attached to database handle db. If successful,
 ** a pointer to the new object is written to *ppSession and SQLITE_OK is
 ** returned. If an error occurs, *ppSession is set to NULL and an SQLite
-** error code (e.g. [SQLITE_NOMEM]) is returned.
+** error code (e.g. SQLITE_NOMEM) is returned.
 **
 ** It is possible to create multiple session objects attached to a single
 ** database handle.
@@ -64,6 +64,9 @@ void sqlite3session_delete(sqlite3_session *pSession);
 ** Enable or disable the recording of changes by a session object. When
 ** enabled, a session object records changes made to the database. When
 ** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
 **
 ** Passing zero to this function disables the session. Passing a value
 ** greater than zero enables it. Passing a value less than zero is a 
@@ -76,11 +79,21 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
 
 /*
 ** Attach a table to a session. All subsequent changes made to the table
-** while the session object is enabled will be recorded.
+** while the session object is enabled will be recorded. See documentation
+** for [sqlite3session_changeset()] for further details.
 **
-** Only tables that have a PRIMARY KEY defined may be attached. It does
-** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
-** or not.
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** defined as part of their CREATE TABLE statement. It does not matter if the 
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+** 
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** SQLITE_OK is returned if the table is successfully attached to the session
+** object. Or, if an error occurs, an SQLite error code (e.g. SQLITE_NOMEM)
+** is returned.
 */
 int sqlite3session_attach(
   sqlite3_session *pSession,      /* Session object */
@@ -95,9 +108,77 @@ int sqlite3session_attach(
 ** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
 ** zero and return an SQLite error code.
 **
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changset_apply()]
+** API.
+**
 ** Following a successful call to this function, it is the responsibility of
 ** the caller to eventually free the buffer that *ppChangeset points to using
 ** [sqlite3_free()].
+**
+** <h2>Changeset Generation</h2>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+**   <li> For each record generated by an insert, the database is queried
+**        for a row with a matching primary key. If one is found, an INSERT
+**        change is added to the changeset. If no such row is found, no change 
+**        is added to the changeset.
+**
+**   <li> For each record generated by an update or delete, the database is 
+**        queried for a row with a matching primary key. If such a row is
+**        found and one or more of the non-primary key fields have been
+**        modified from their original values, an UPDATE change is added to 
+**        the changeset. Or, if no such row is found in the table, a DELETE 
+**        change is added to the changeset. If there is a row with a matching
+**        primary key in the database, but all fields contain their original
+**        values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert or the delete
+** will be present in the changeset. Or if a row is deleted and then later a 
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
+** is inserted while a session object is enabled, then later deleted while 
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
+** Or, if one field of a row is updated while a session is disabled, and 
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
 */
 int sqlite3session_changeset(
   sqlite3_session *pSession,      /* Session object */
@@ -107,27 +188,73 @@ int sqlite3session_changeset(
 
 /*
 ** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
+** The following functions can be used to advance and query a changeset 
+** iterator created by this function:
+**
+** <ul>
+**   <li> [sqlite3changeset_next()]
+**   <li> [sqlite3changeset_op()]
+**   <li> [sqlite3changeset_new()]
+**   <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
 */
 int sqlite3changeset_start(
-  sqlite3_changeset_iter **ppIter,
-  int nChangeset, 
-  void *pChangeset
+  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+  int nChangeset,                 /* Size of changeset blob in bytes */
+  void *pChangeset                /* Pointer to blob containing changeset */
 );
 
 /*
-** Advance an iterator created by sqlite3changeset_start() to the next
-** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
-** or SQLITE_CORRUPT.
+** This function may only be used with iterators created by function
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
 **
-** This function may not be called on iterators passed to a conflict handler
-** callback by changeset_apply().
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
+** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
+** If an error occurs, an SQLite error code is returned. Possible error 
+** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
+** SQLITE_NOMEM.
 */
 int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
 
 /*
-** The following three functions extract information on the current change
-** from a changeset iterator. They may only be called after changeset_next()
-** has returned SQLITE_ROW.
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. If this
+** is not the case, this function returns SQLITE_MISUSE.
+**
+** If argument pzTab is not NULL, then *pzTab is set to point to a
+** nul-terminated utf-8 encoded string containing the name of the table
+** affected by the current change. The buffer remains valid until either
+** sqlite3changeset_next() is called on the iterator or until the 
+** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
+** set to the number of columns in the table affected by the change. Finally,
+** if pOp is not NULL, then *pOp is set to one of SQLITE_INSERT, SQLITE_DELETE
+** or SQLITE_UPDATE, depending on the type of change that the iterator
+** currently points to.
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
 */
 int sqlite3changeset_op(
   sqlite3_changeset_iter *pIter,  /* Iterator object */
@@ -135,11 +262,60 @@ int sqlite3changeset_op(
   int *pnCol,                     /* OUT: Number of columns in table */
   int *pOp                        /* OUT: SQLITE_INSERT, DELETE or UPDATE */
 );
+
+/*
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either SQLITE_DELETE or SQLITE_UPDATE. Otherwise,
+** this function returns SQLITE_MISUSE and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** SQLITE_RANGE is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** original row values stored as part of the UPDATE or DELETE change and
+** returns SQLITE_OK. The name of the function comes from the fact that this 
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
 int sqlite3changeset_old(
   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
   int iVal,                       /* Column number */
   sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
 );
+
+/*
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either SQLITE_UPDATE or SQLITE_INSERT. Otherwise,
+** this function returns SQLITE_MISUSE and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** SQLITE_RANGE is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
+** a new value for the requested column, *ppValue is set to NULL and 
+** SQLITE_OK returned. The name of the function comes from the fact that 
+** this is similar to the "new.*" columns available to update or delete 
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
 int sqlite3changeset_new(
   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
   int iVal,                       /* Column number */
@@ -147,13 +323,23 @@ int sqlite3changeset_new(
 );
 
 /*
-** This function is only usable with sqlite3_changeset_iter objects passed
-** to the xConflict callback by sqlite3changeset_apply(). It cannot be used
-** with iterators created using sqlite3changeset_start().
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this function
+** is called on any other iterator, SQLITE_MISUSE is returned and *ppValue
+** is set to NULL.
 **
-** It is used to access the "conflicting row" information available to the
-** conflict handler if the second argument is either SQLITE_CHANGESET_DATA
-** or SQLITE_CHANGESET_CONFLICT.
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** SQLITE_RANGE is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the 
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
 */
 int sqlite3changeset_conflict(
   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
@@ -165,8 +351,26 @@ int sqlite3changeset_conflict(
 /*
 ** Finalize an iterator allocated with sqlite3changeset_start().
 **
-** This function may not be called on iterators passed to a conflict handler
-** callback by changeset_apply().
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], SQLITE_MISUSE is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
+** function (for example an SQLITE_CORRUPT in sqlite3changeset_next() or an 
+** SQLITE_NOMEM in sqlite3changeset_new()) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
+**   sqlite3changeset_start();
+**   while( SQLITE_ROW==sqlite3changeset_next() ){
+**     // Do something with change.
+**   }
+**   rc = sqlite3changeset_finalize();
+**   if( rc!=SQLITE_OK ){
+**     // An error has occurred 
+**   }
 */
 int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
 
old mode 100755 (executable)
new mode 100644 (file)
index 212e1e98516bf5e96f75cea16a212a96252e6f5d..a137b38bb3f9a5f78970f2e962ea9d1b132474e7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Merge\sall\sthe\slatest\strunk\senhancements\sinto\sthe\ssessions\sbranch.
-D 2011-03-18T12:35:36.113
+C Update\scomments\sin\ssqlite3session.h.\sMore\sto\scome.
+D 2011-03-18T13:05:15
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -103,9 +100,9 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
 F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503
-F ext/session/sqlite3session.h 63045871564085669b5cb1fb92e6efc2e1b1120a
+F ext/session/sqlite3session.h 3e342facbb95589dfba34545df383df68cc44ebf
 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
-F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
+F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7
 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
@@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6
 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
-F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
+F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8
@@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027
 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
 F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309
-F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
+F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3
 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff
@@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 6614cfcb9c41da71ddec3c44a3de0d4d849e1cdd 54bacb95dd6e2d6ac4971391a40484ccb9126d29
-R e54868c8ee7f58a0691b9e0694987cf6
-U drh
-Z 8149dc4ff84780eb7c2d29113d1dc5ec
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFNg1GboxKgR168RlERAptpAJ4+cfNBHl8w0y578KOanLZsuj14mgCffUXp
-W65/Ci2dAe+flL3fcPt3X+4=
-=uYuP
------END PGP SIGNATURE-----
+P 94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6
+R eb9573de7a3fa964ba524a7a8e9a976a
+U dan
+Z f742ca024227ec41f9ba4edac43a23a5
index 2d0f8d52c673547570984a73033dae51195c04f8..d587d908a18dfca9d7eb29770bea4d3e3f858ed4 100644 (file)
@@ -1 +1 @@
-94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6
\ No newline at end of file
+e73e9082f3b14088752717193a10dd7657deb8af
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)