14fccf43aSdan 
24fccf43aSdan #ifndef __SQLITESESSION_H_
34fccf43aSdan #define __SQLITESESSION_H_ 1
44fccf43aSdan 
54fccf43aSdan /*
64fccf43aSdan ** Make sure we can call this stuff from C++.
74fccf43aSdan */
84fccf43aSdan #ifdef __cplusplus
94fccf43aSdan extern "C" {
104fccf43aSdan #endif
114fccf43aSdan 
124fccf43aSdan #include "sqlite3.h"
134fccf43aSdan 
14a2df3d9fSdan /*
15a2df3d9fSdan ** CAPI3REF: Session Object Handle
16a2df3d9fSdan */
174fccf43aSdan typedef struct sqlite3_session sqlite3_session;
18a2df3d9fSdan 
19a2df3d9fSdan /*
20a2df3d9fSdan ** CAPI3REF: Changeset Iterator Handle
21a2df3d9fSdan */
224fccf43aSdan typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
234fccf43aSdan 
244fccf43aSdan /*
25a2df3d9fSdan ** CAPI3REF: Create A New Session Object
26a2df3d9fSdan **
2737db03bfSdan ** Create a new session object attached to database handle db. If successful,
2837db03bfSdan ** a pointer to the new object is written to *ppSession and SQLITE_OK is
2937db03bfSdan ** returned. If an error occurs, *ppSession is set to NULL and an SQLite
30c21111daSdan ** error code (e.g. SQLITE_NOMEM) is returned.
3137db03bfSdan **
3237db03bfSdan ** It is possible to create multiple session objects attached to a single
3337db03bfSdan ** database handle.
3437db03bfSdan **
3537db03bfSdan ** Session objects created using this function should be deleted using the
3637db03bfSdan ** [sqlite3session_delete()] function before the database handle that they
3737db03bfSdan ** are attached to is itself closed. If the database handle is closed before
3837db03bfSdan ** the session object is deleted, then the results of calling any session
3937db03bfSdan ** module function, including [sqlite3session_delete()] on the session object
4037db03bfSdan ** are undefined.
4137db03bfSdan **
4237db03bfSdan ** Because the session module uses the [sqlite3_preupdate_hook()] API, it
4337db03bfSdan ** is not possible for an application to register a pre-update hook on a
4437db03bfSdan ** database handle that has one or more session objects attached. Nor is
4537db03bfSdan ** it possible to create a session object attached to a database handle for
4637db03bfSdan ** which a pre-update hook is already defined. The results of attempting
4737db03bfSdan ** either of these things are undefined.
4837db03bfSdan **
4937db03bfSdan ** The session object will be used to create changesets for tables in
5037db03bfSdan ** database zDb, where zDb is either "main", or "temp", or the name of an
51ca62ad57Sdan ** attached database. It is not an error if database zDb is not attached
5237db03bfSdan ** to the database when the session object is created.
534fccf43aSdan */
544fccf43aSdan int sqlite3session_create(
554fccf43aSdan   sqlite3 *db,                    /* Database handle */
564fccf43aSdan   const char *zDb,                /* Name of db (e.g. "main") */
574fccf43aSdan   sqlite3_session **ppSession     /* OUT: New session object */
584fccf43aSdan );
594fccf43aSdan 
604fccf43aSdan /*
61a2df3d9fSdan ** CAPI3REF: Delete A Session Object
62a2df3d9fSdan **
6337db03bfSdan ** Delete a session object previously allocated using
6437db03bfSdan ** [sqlite3session_create()]. Once a session object has been deleted, the
6537db03bfSdan ** results of attempting to use pSession with any other session module
6637db03bfSdan ** function are undefined.
6737db03bfSdan **
6837db03bfSdan ** Session objects must be deleted before the database handle to which they
6937db03bfSdan ** are attached is closed. Refer to the documentation for
7037db03bfSdan ** [sqlite3session_create()] for details.
7137db03bfSdan */
7237db03bfSdan void sqlite3session_delete(sqlite3_session *pSession);
7337db03bfSdan 
7437db03bfSdan /*
75a2df3d9fSdan ** CAPI3REF: Enable Or Disable A Session Object
76a2df3d9fSdan **
774fccf43aSdan ** Enable or disable the recording of changes by a session object. When
784fccf43aSdan ** enabled, a session object records changes made to the database. When
794fccf43aSdan ** disabled - it does not. A newly created session object is enabled.
80c21111daSdan ** Refer to the documentation for [sqlite3session_changeset()] for further
81c21111daSdan ** details regarding how enabling and disabling a session object affects
82c21111daSdan ** the eventual changesets.
834fccf43aSdan **
844fccf43aSdan ** Passing zero to this function disables the session. Passing a value
854fccf43aSdan ** greater than zero enables it. Passing a value less than zero is a
864fccf43aSdan ** no-op, and may be used to query the current state of the session.
874fccf43aSdan **
884fccf43aSdan ** The return value indicates the final state of the session object: 0 if
894fccf43aSdan ** the session is disabled, or 1 if it is enabled.
904fccf43aSdan */
914fccf43aSdan int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
924fccf43aSdan 
934fccf43aSdan /*
94b4480e94Sdan ** CAPI3REF: Set Or Clear the Indirect Change Flag
95b4480e94Sdan **
96b4480e94Sdan ** Each change recorded by a session object is marked as either direct or
97b4480e94Sdan ** indirect. A change is marked as indirect if either:
98b4480e94Sdan **
99b4480e94Sdan ** <ul>
100b4480e94Sdan **   <li> The session object "indirect" flag is set when the change is
101b4480e94Sdan **        made, or
102b4480e94Sdan **   <li> The change is made by an SQL trigger or foreign key action
103b4480e94Sdan **        instead of directly as a result of a users SQL statement.
104b4480e94Sdan ** </ul>
105b4480e94Sdan **
106b4480e94Sdan ** If a single row is affected by more than one operation within a session,
107b4480e94Sdan ** then the change is considered indirect if all operations meet the criteria
108b4480e94Sdan ** for an indirect change above, or direct otherwise.
109b4480e94Sdan **
110b4480e94Sdan ** This function is used to set, clear or query the session object indirect
111b4480e94Sdan ** flag.  If the second argument passed to this function is zero, then the
112b4480e94Sdan ** indirect flag is cleared. If it is greater than zero, the indirect flag
113b4480e94Sdan ** is set. Passing a value less than zero does not modify the current value
114b4480e94Sdan ** of the indirect flag, and may be used to query the current state of the
115b4480e94Sdan ** indirect flag for the specified session object.
116b4480e94Sdan **
117b4480e94Sdan ** The return value indicates the final state of the indirect flag: 0 if
118b4480e94Sdan ** it is clear, or 1 if it is set.
119b4480e94Sdan */
120b4480e94Sdan int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
121b4480e94Sdan 
122b4480e94Sdan /*
123157546f4Sshaneh ** CAPI3REF: Attach A Table To A Session Object
124a2df3d9fSdan **
125ff4d0f41Sdan ** If argument zTab is not NULL, then it is the name of a table to attach
126ff4d0f41Sdan ** to the session object passed as the first argument. All subsequent changes
127ff4d0f41Sdan ** made to the table while the session object is enabled will be recorded. See
128ff4d0f41Sdan ** documentation for [sqlite3session_changeset()] for further details.
129ff4d0f41Sdan **
130ff4d0f41Sdan ** Or, if argument zTab is NULL, then changes are recorded for all tables
131ff4d0f41Sdan ** in the database. If additional tables are added to the database (by
132ff4d0f41Sdan ** executing "CREATE TABLE" statements) after this call is made, changes for
133ff4d0f41Sdan ** the new tables are also recorded.
1344fccf43aSdan **
135c21111daSdan ** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
136c21111daSdan ** defined as part of their CREATE TABLE statement. It does not matter if the
137c21111daSdan ** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
138c21111daSdan ** KEY may consist of a single column, or may be a composite key.
139c21111daSdan **
140c21111daSdan ** It is not an error if the named table does not exist in the database. Nor
141c21111daSdan ** is it an error if the named table does not have a PRIMARY KEY. However,
142c21111daSdan ** no changes will be recorded in either of these scenarios.
143c21111daSdan **
14427453faeSdan ** Changes are not recorded for individual rows that have NULL values stored
14527453faeSdan ** in one or more of their PRIMARY KEY columns.
14627453faeSdan **
147ff4d0f41Sdan ** SQLITE_OK is returned if the call completes without error. Or, if an error
148ff4d0f41Sdan ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
1494fccf43aSdan */
1504fccf43aSdan int sqlite3session_attach(
1514fccf43aSdan   sqlite3_session *pSession,      /* Session object */
1524fccf43aSdan   const char *zTab                /* Table name */
1534fccf43aSdan );
1544fccf43aSdan 
1554fccf43aSdan /*
156a2df3d9fSdan ** CAPI3REF: Generate A Changeset From A Session Object
157a2df3d9fSdan **
15837db03bfSdan ** Obtain a changeset containing changes to the tables attached to the
15937db03bfSdan ** session object passed as the first argument. If successful,
16037db03bfSdan ** set *ppChangeset to point to a buffer containing the changeset
16137db03bfSdan ** and *pnChangeset to the size of the changeset in bytes before returning
16237db03bfSdan ** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
16337db03bfSdan ** zero and return an SQLite error code.
1644fccf43aSdan **
165c21111daSdan ** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
166c21111daSdan ** each representing a change to a single row of an attached table. An INSERT
167c21111daSdan ** change contains the values of each field of a new database row. A DELETE
168c21111daSdan ** contains the original values of each field of a deleted database row. An
169c21111daSdan ** UPDATE change contains the original values of each field of an updated
170c21111daSdan ** database row along with the updated values for each updated non-primary-key
171c21111daSdan ** column. It is not possible for an UPDATE change to represent a change that
172c21111daSdan ** modifies the values of primary key columns. If such a change is made, it
173c21111daSdan ** is represented in a changeset as a DELETE followed by an INSERT.
174c21111daSdan **
17527453faeSdan ** Changes are not recorded for rows that have NULL values stored in one or
17627453faeSdan ** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
17727453faeSdan ** no corresponding change is present in the changesets returned by this
17827453faeSdan ** function. If an existing row with one or more NULL values stored in
17927453faeSdan ** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
18027453faeSdan ** only an INSERT is appears in the changeset. Similarly, if an existing row
18127453faeSdan ** with non-NULL PRIMARY KEY values is updated so that one or more of its
18227453faeSdan ** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
18327453faeSdan ** DELETE change only.
18427453faeSdan **
185c21111daSdan ** The contents of a changeset may be traversed using an iterator created
186c21111daSdan ** using the [sqlite3changeset_start()] API. A changeset may be applied to
187a2df3d9fSdan ** a database with a compatible schema using the [sqlite3changeset_apply()]
188c21111daSdan ** API.
189c21111daSdan **
19037db03bfSdan ** Following a successful call to this function, it is the responsibility of
19137db03bfSdan ** the caller to eventually free the buffer that *ppChangeset points to using
19237db03bfSdan ** [sqlite3_free()].
193c21111daSdan **
194a2df3d9fSdan ** <h3>Changeset Generation</h3>
195c21111daSdan **
196c21111daSdan ** Once a table has been attached to a session object, the session object
197c21111daSdan ** records the primary key values of all new rows inserted into the table.
198c21111daSdan ** It also records the original primary key and other column values of any
199c21111daSdan ** deleted or updated rows. For each unique primary key value, data is only
200c21111daSdan ** recorded once - the first time a row with said primary key is inserted,
201c21111daSdan ** updated or deleted in the lifetime of the session.
202c21111daSdan **
20327453faeSdan ** There is one exception to the previous paragraph: when a row is inserted,
204157546f4Sshaneh ** updated or deleted, if one or more of its primary key columns contain a
20527453faeSdan ** NULL value, no record of the change is made.
20627453faeSdan **
207c21111daSdan ** The session object therefore accumulates two types of records - those
208c21111daSdan ** that consist of primary key values only (created when the user inserts
209c21111daSdan ** a new record) and those that consist of the primary key values and the
210c21111daSdan ** original values of other table columns (created when the users deletes
211c21111daSdan ** or updates a record).
212c21111daSdan **
213c21111daSdan ** When this function is called, the requested changeset is created using
214c21111daSdan ** both the accumulated records and the current contents of the database
215c21111daSdan ** file. Specifically:
216c21111daSdan **
217c21111daSdan ** <ul>
218c21111daSdan **   <li> For each record generated by an insert, the database is queried
219c21111daSdan **        for a row with a matching primary key. If one is found, an INSERT
220c21111daSdan **        change is added to the changeset. If no such row is found, no change
221c21111daSdan **        is added to the changeset.
222c21111daSdan **
223c21111daSdan **   <li> For each record generated by an update or delete, the database is
224c21111daSdan **        queried for a row with a matching primary key. If such a row is
225c21111daSdan **        found and one or more of the non-primary key fields have been
226c21111daSdan **        modified from their original values, an UPDATE change is added to
227c21111daSdan **        the changeset. Or, if no such row is found in the table, a DELETE
228c21111daSdan **        change is added to the changeset. If there is a row with a matching
229c21111daSdan **        primary key in the database, but all fields contain their original
230c21111daSdan **        values, no change is added to the changeset.
231c21111daSdan ** </ul>
232c21111daSdan **
233c21111daSdan ** This means, amongst other things, that if a row is inserted and then later
234157546f4Sshaneh ** deleted while a session object is active, neither the insert nor the delete
235c21111daSdan ** will be present in the changeset. Or if a row is deleted and then later a
236c21111daSdan ** row with the same primary key values inserted while a session object is
237c21111daSdan ** active, the resulting changeset will contain an UPDATE change instead of
238c21111daSdan ** a DELETE and an INSERT.
239c21111daSdan **
240c21111daSdan ** When a session object is disabled (see the [sqlite3session_enable()] API),
241c21111daSdan ** it does not accumulate records when rows are inserted, updated or deleted.
242c21111daSdan ** This may appear to have some counter-intuitive effects if a single row
243c21111daSdan ** is written to more than once during a session. For example, if a row
244c21111daSdan ** is inserted while a session object is enabled, then later deleted while
245c21111daSdan ** the same session object is disabled, no INSERT record will appear in the
246c21111daSdan ** changeset, even though the delete took place while the session was disabled.
247c21111daSdan ** Or, if one field of a row is updated while a session is disabled, and
248c21111daSdan ** another field of the same row is updated while the session is enabled, the
249c21111daSdan ** resulting changeset will contain an UPDATE change that updates both fields.
2504fccf43aSdan */
2514fccf43aSdan int sqlite3session_changeset(
2524fccf43aSdan   sqlite3_session *pSession,      /* Session object */
2534fccf43aSdan   int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
2544fccf43aSdan   void **ppChangeset              /* OUT: Buffer containing changeset */
2554fccf43aSdan );
2564fccf43aSdan 
2574fccf43aSdan /*
258b69ec348Sdan ** CAPI3REF: Test if a changeset has recorded any changes.
259b69ec348Sdan **
260b69ec348Sdan ** Return non-zero if no changes to attached tables have been recorded by
261b69ec348Sdan ** the session object passed as the first argument. Otherwise, if one or
262b69ec348Sdan ** more changes have been recorded, return zero.
263b69ec348Sdan **
264b69ec348Sdan ** Even if this function returns zero, it is possible that calling
265b69ec348Sdan ** [sqlite3session_changeset()] on the session handle may still return a
266b69ec348Sdan ** changeset that contains no changes. This can happen when a row in
267b69ec348Sdan ** an attached table is modified and then later on the original values
268b69ec348Sdan ** are restored. However, if this function returns non-zero, then it is
269b69ec348Sdan ** guaranteed that a call to sqlite3session_changeset() will return a
270b69ec348Sdan ** changeset containing zero changes.
271b69ec348Sdan */
272b69ec348Sdan int sqlite3session_isempty(sqlite3_session *pSession);
273b69ec348Sdan 
274b69ec348Sdan /*
275a2df3d9fSdan ** CAPI3REF: Create An Iterator To Traverse A Changeset
276a2df3d9fSdan **
2774fccf43aSdan ** Create an iterator used to iterate through the contents of a changeset.
278c21111daSdan ** If successful, *pp is set to point to the iterator handle and SQLITE_OK
279c21111daSdan ** is returned. Otherwise, if an error occurs, *pp is set to zero and an
280c21111daSdan ** SQLite error code is returned.
281c21111daSdan **
282c21111daSdan ** The following functions can be used to advance and query a changeset
283c21111daSdan ** iterator created by this function:
284c21111daSdan **
285c21111daSdan ** <ul>
286c21111daSdan **   <li> [sqlite3changeset_next()]
287c21111daSdan **   <li> [sqlite3changeset_op()]
288c21111daSdan **   <li> [sqlite3changeset_new()]
289c21111daSdan **   <li> [sqlite3changeset_old()]
290c21111daSdan ** </ul>
291c21111daSdan **
292c21111daSdan ** It is the responsibility of the caller to eventually destroy the iterator
293c21111daSdan ** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
294c21111daSdan ** changeset (pChangeset) must remain valid until after the iterator is
295c21111daSdan ** destroyed.
296b69ec348Sdan **
297b69ec348Sdan ** Assuming the changeset blob was created by one of the
298b69ec348Sdan ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
299a93166e0Sdan ** [sqlite3changeset_invert()] functions, all changes within the changeset
300a93166e0Sdan ** that apply to a single table are grouped together. This means that when
301a93166e0Sdan ** an application iterates through a changeset using an iterator created by
302a93166e0Sdan ** this function, all changes that relate to a single table are visted
303a93166e0Sdan ** consecutively. There is no chance that the iterator will visit a change
304a93166e0Sdan ** the applies to table X, then one for table Y, and then later on visit
305a93166e0Sdan ** another change for table X.
3064fccf43aSdan */
3074fccf43aSdan int sqlite3changeset_start(
308c21111daSdan   sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
309c21111daSdan   int nChangeset,                 /* Size of changeset blob in bytes */
310c21111daSdan   void *pChangeset                /* Pointer to blob containing changeset */
3114fccf43aSdan );
3124fccf43aSdan 
3134fccf43aSdan /*
314a2df3d9fSdan ** CAPI3REF: Advance A Changeset Iterator
315a2df3d9fSdan **
316c21111daSdan ** This function may only be used with iterators created by function
317c21111daSdan ** [sqlite3changeset_start()]. If it is called on an iterator passed to
318c21111daSdan ** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
319c21111daSdan ** is returned and the call has no effect.
3204fccf43aSdan **
321c21111daSdan ** Immediately after an iterator is created by sqlite3changeset_start(), it
322c21111daSdan ** does not point to any change in the changeset. Assuming the changeset
323c21111daSdan ** is not empty, the first call to this function advances the iterator to
324c21111daSdan ** point to the first change in the changeset. Each subsequent call advances
325c21111daSdan ** the iterator to point to the next change in the changeset (if any). If
326c21111daSdan ** no error occurs and the iterator points to a valid change after a call
327c21111daSdan ** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned.
328c21111daSdan ** Otherwise, if all changes in the changeset have already been visited,
329c21111daSdan ** SQLITE_DONE is returned.
330c21111daSdan **
331c21111daSdan ** If an error occurs, an SQLite error code is returned. Possible error
332c21111daSdan ** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or
333c21111daSdan ** SQLITE_NOMEM.
3344fccf43aSdan */
3354fccf43aSdan int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
3364fccf43aSdan 
3374fccf43aSdan /*
338a2df3d9fSdan ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
339a2df3d9fSdan **
340c21111daSdan ** The pIter argument passed to this function may either be an iterator
341c21111daSdan ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
342c21111daSdan ** created by [sqlite3changeset_start()]. In the latter case, the most recent
34377e65004Sdan ** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
34477e65004Sdan ** is not the case, this function returns [SQLITE_MISUSE].
345c21111daSdan **
346c21111daSdan ** If argument pzTab is not NULL, then *pzTab is set to point to a
347c21111daSdan ** nul-terminated utf-8 encoded string containing the name of the table
348c21111daSdan ** affected by the current change. The buffer remains valid until either
349c21111daSdan ** sqlite3changeset_next() is called on the iterator or until the
350c21111daSdan ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is
351b4480e94Sdan ** set to the number of columns in the table affected by the change. If
352b4480e94Sdan ** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
353b4480e94Sdan ** is an indirect change, or false (0) otherwise. See the documentation for
354b4480e94Sdan ** [sqlite3session_indirect()] for a description of direct and indirect
355b4480e94Sdan ** changes. Finally, if pOp is not NULL, then *pOp is set to one of
356b4480e94Sdan ** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the
357b4480e94Sdan ** type of change that the iterator currently points to.
358c21111daSdan **
359c21111daSdan ** If no error occurs, SQLITE_OK is returned. If an error does occur, an
360c21111daSdan ** SQLite error code is returned. The values of the output variables may not
361c21111daSdan ** be trusted in this case.
3624fccf43aSdan */
3634fccf43aSdan int sqlite3changeset_op(
3644fccf43aSdan   sqlite3_changeset_iter *pIter,  /* Iterator object */
3654fccf43aSdan   const char **pzTab,             /* OUT: Pointer to table name */
3664fccf43aSdan   int *pnCol,                     /* OUT: Number of columns in table */
367b4480e94Sdan   int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
368b4480e94Sdan   int *pbIndirect                 /* OUT: True for an 'indirect' change */
3694fccf43aSdan );
370c21111daSdan 
371c21111daSdan /*
372244593c8Sdan ** CAPI3REF: Obtain The Primary Key Definition Of A Table
373244593c8Sdan **
374244593c8Sdan ** For each modified table, a changeset includes the following:
375244593c8Sdan **
376244593c8Sdan ** <ul>
377244593c8Sdan **   <li> The number of columns in the table, and
378244593c8Sdan **   <li> Which of those columns make up the tables PRIMARY KEY.
379244593c8Sdan ** </ul>
380244593c8Sdan **
381244593c8Sdan ** This function is used to find which columns comprise the PRIMARY KEY of
382244593c8Sdan ** the table modified by the change that iterator pIter currently points to.
383244593c8Sdan ** If successful, *pabPK is set to point to an array of nCol entries, where
384244593c8Sdan ** nCol is the number of columns in the table. Elements of *pabPK are set to
385244593c8Sdan ** 0x01 if the corresponding column is part of the tables primary key, or
386244593c8Sdan ** 0x00 if it is not.
387244593c8Sdan **
388244593c8Sdan ** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
389244593c8Sdan ** in the table.
390244593c8Sdan **
391244593c8Sdan ** If this function is called when the iterator does not point to a valid
392244593c8Sdan ** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
393244593c8Sdan ** SQLITE_OK is returned and the output variables populated as described
394244593c8Sdan ** above.
395244593c8Sdan */
396244593c8Sdan int sqlite3changeset_pk(
397244593c8Sdan   sqlite3_changeset_iter *pIter,  /* Iterator object */
398244593c8Sdan   unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
399244593c8Sdan   int *pnCol                      /* OUT: Number of entries in output array */
400244593c8Sdan );
401244593c8Sdan 
402244593c8Sdan /*
403a2df3d9fSdan ** CAPI3REF: Obtain old.* Values From A Changeset Iterator
404a2df3d9fSdan **
405c21111daSdan ** The pIter argument passed to this function may either be an iterator
406c21111daSdan ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
407c21111daSdan ** created by [sqlite3changeset_start()]. In the latter case, the most recent
408c21111daSdan ** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
409c21111daSdan ** Furthermore, it may only be called if the type of change that the iterator
41077e65004Sdan ** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
41177e65004Sdan ** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
412c21111daSdan **
413c21111daSdan ** Argument iVal must be greater than or equal to 0, and less than the number
414c21111daSdan ** of columns in the table affected by the current change. Otherwise,
41577e65004Sdan ** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
416c21111daSdan **
417c21111daSdan ** If successful, this function sets *ppValue to point to a protected
418c21111daSdan ** sqlite3_value object containing the iVal'th value from the vector of
419c21111daSdan ** original row values stored as part of the UPDATE or DELETE change and
420c21111daSdan ** returns SQLITE_OK. The name of the function comes from the fact that this
421c21111daSdan ** is similar to the "old.*" columns available to update or delete triggers.
422c21111daSdan **
423c21111daSdan ** If some other error occurs (e.g. an OOM condition), an SQLite error code
424c21111daSdan ** is returned and *ppValue is set to NULL.
425c21111daSdan */
4264fccf43aSdan int sqlite3changeset_old(
427296c7658Sdan   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
428296c7658Sdan   int iVal,                       /* Column number */
4294fccf43aSdan   sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
4304fccf43aSdan );
431c21111daSdan 
432c21111daSdan /*
433a2df3d9fSdan ** CAPI3REF: Obtain new.* Values From A Changeset Iterator
434a2df3d9fSdan **
435c21111daSdan ** The pIter argument passed to this function may either be an iterator
436c21111daSdan ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
437c21111daSdan ** created by [sqlite3changeset_start()]. In the latter case, the most recent
438c21111daSdan ** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
439c21111daSdan ** Furthermore, it may only be called if the type of change that the iterator
44077e65004Sdan ** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
44177e65004Sdan ** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
442c21111daSdan **
443c21111daSdan ** Argument iVal must be greater than or equal to 0, and less than the number
444c21111daSdan ** of columns in the table affected by the current change. Otherwise,
44577e65004Sdan ** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
446c21111daSdan **
447c21111daSdan ** If successful, this function sets *ppValue to point to a protected
448c21111daSdan ** sqlite3_value object containing the iVal'th value from the vector of
449c21111daSdan ** new row values stored as part of the UPDATE or INSERT change and
450c21111daSdan ** returns SQLITE_OK. If the change is an UPDATE and does not include
451c21111daSdan ** a new value for the requested column, *ppValue is set to NULL and
452c21111daSdan ** SQLITE_OK returned. The name of the function comes from the fact that
453c21111daSdan ** this is similar to the "new.*" columns available to update or delete
454c21111daSdan ** triggers.
455c21111daSdan **
456c21111daSdan ** If some other error occurs (e.g. an OOM condition), an SQLite error code
457c21111daSdan ** is returned and *ppValue is set to NULL.
458c21111daSdan */
4594fccf43aSdan int sqlite3changeset_new(
460296c7658Sdan   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
461296c7658Sdan   int iVal,                       /* Column number */
4624fccf43aSdan   sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
4634fccf43aSdan );
464296c7658Sdan 
465d5f0767cSdan /*
466a2df3d9fSdan ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
467a2df3d9fSdan **
468c21111daSdan ** This function should only be used with iterator objects passed to a
469c21111daSdan ** conflict-handler callback by [sqlite3changeset_apply()] with either
47077e65004Sdan ** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
47177e65004Sdan ** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
472c21111daSdan ** is set to NULL.
473d5f0767cSdan **
474c21111daSdan ** Argument iVal must be greater than or equal to 0, and less than the number
475c21111daSdan ** of columns in the table affected by the current change. Otherwise,
47677e65004Sdan ** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
477c21111daSdan **
478c21111daSdan ** If successful, this function sets *ppValue to point to a protected
479c21111daSdan ** sqlite3_value object containing the iVal'th value from the
480c21111daSdan ** "conflicting row" associated with the current conflict-handler callback
481c21111daSdan ** and returns SQLITE_OK.
482c21111daSdan **
483c21111daSdan ** If some other error occurs (e.g. an OOM condition), an SQLite error code
484c21111daSdan ** is returned and *ppValue is set to NULL.
485d5f0767cSdan */
486d5f0767cSdan int sqlite3changeset_conflict(
487296c7658Sdan   sqlite3_changeset_iter *pIter,  /* Changeset iterator */
488296c7658Sdan   int iVal,                       /* Column number */
489d5f0767cSdan   sqlite3_value **ppValue         /* OUT: Value from conflicting row */
490d5f0767cSdan );
491d5f0767cSdan 
4924fccf43aSdan 
4934fccf43aSdan /*
494157546f4Sshaneh ** CAPI3REF: Finalize A Changeset Iterator
495a2df3d9fSdan **
496a2df3d9fSdan ** This function is used to finalize an iterator allocated with
49777e65004Sdan ** [sqlite3changeset_start()].
4984fccf43aSdan **
499c21111daSdan ** This function should only be called on iterators created using the
500c21111daSdan ** [sqlite3changeset_start()] function. If an application calls this
501c21111daSdan ** function with an iterator passed to a conflict-handler by
50277e65004Sdan ** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
503c21111daSdan ** call has no effect.
504c21111daSdan **
505c21111daSdan ** If an error was encountered within a call to an sqlite3changeset_xxx()
50677e65004Sdan ** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an
50777e65004Sdan ** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
508c21111daSdan ** to that error is returned by this function. Otherwise, SQLITE_OK is
509c21111daSdan ** returned. This is to allow the following pattern (pseudo-code):
510c21111daSdan **
511c21111daSdan **   sqlite3changeset_start();
512c21111daSdan **   while( SQLITE_ROW==sqlite3changeset_next() ){
513c21111daSdan **     // Do something with change.
514c21111daSdan **   }
515c21111daSdan **   rc = sqlite3changeset_finalize();
516c21111daSdan **   if( rc!=SQLITE_OK ){
517c21111daSdan **     // An error has occurred
518c21111daSdan **   }
5194fccf43aSdan */
5204fccf43aSdan int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
5214fccf43aSdan 
52291ddd559Sdan /*
523a2df3d9fSdan ** CAPI3REF: Invert A Changeset
524a2df3d9fSdan **
5252635a3beSdan ** This function is used to "invert" a changeset object. Applying an inverted
5262635a3beSdan ** changeset to a database reverses the effects of applying the uninverted
5272635a3beSdan ** changeset. Specifically:
5282635a3beSdan **
5292635a3beSdan ** <ul>
5302635a3beSdan **   <li> Each DELETE change is changed to an INSERT, and
5312635a3beSdan **   <li> Each INSERT change is changed to a DELETE, and
5322635a3beSdan **   <li> For each UPDATE change, the old.* and new.* values are exchanged.
5332635a3beSdan ** </ul>
5342635a3beSdan **
5352635a3beSdan ** If successful, a pointer to a buffer containing the inverted changeset
5362635a3beSdan ** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
5372635a3beSdan ** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
5382635a3beSdan ** zeroed and an SQLite error code returned.
5392635a3beSdan **
5402635a3beSdan ** It is the responsibility of the caller to eventually call sqlite3_free()
5412635a3beSdan ** on the *ppOut pointer to free the buffer allocation following a successful
5422635a3beSdan ** call to this function.
543f51e5f6cSdan **
544f51e5f6cSdan ** WARNING/TODO: This function currently assumes that the input is a valid
545f51e5f6cSdan ** changeset. If it is not, the results are undefined.
54691ddd559Sdan */
54791ddd559Sdan int sqlite3changeset_invert(
548*cfec7eeeSdan   int nIn, const void *pIn,       /* Input changeset */
54991ddd559Sdan   int *pnOut, void **ppOut        /* OUT: Inverse of input */
55091ddd559Sdan );
55191ddd559Sdan 
5526cda207fSdan /*
55329e03e97Sdan ** CAPI3REF: Concatenate Two Changeset Objects
55429e03e97Sdan **
55529e03e97Sdan ** This function is used to concatenate two changesets, A and B, into a
55629e03e97Sdan ** single changeset. The result is a changeset equivalent to applying
55729e03e97Sdan ** changeset A followed by changeset B.
55829e03e97Sdan **
55929e03e97Sdan ** Rows are identified by the values in their PRIMARY KEY columns. A change
56029e03e97Sdan ** in changeset A is considered to apply to the same row as a change in
56129e03e97Sdan ** changeset B if the two rows have the same primary key.
56229e03e97Sdan **
56329e03e97Sdan ** Changes to rows that appear only in changeset A or B are copied into the
56429e03e97Sdan ** output changeset. Or, if both changeset A and B contain a change that
56529e03e97Sdan ** applies to a single row, the output depends on the type of each change,
56629e03e97Sdan ** as follows:
56729e03e97Sdan **
56829e03e97Sdan ** <table border=1 style="margin-left:8ex;margin-right:8ex">
56929e03e97Sdan **   <tr><th style="white-space:pre">Change A      </th>
57029e03e97Sdan **       <th style="white-space:pre">Change B      </th>
57129e03e97Sdan **       <th>Output Change
57229e03e97Sdan **   <tr><td>INSERT <td>INSERT <td>
57329e03e97Sdan **       Change A is copied into the output changeset. Change B is discarded.
57429e03e97Sdan **       This case does not occur if changeset B is recorded immediately after
57529e03e97Sdan **       changeset A.
57629e03e97Sdan **   <tr><td>INSERT <td>UPDATE <td>
57729e03e97Sdan **       An INSERT change is copied into the output changeset. The values in
57829e03e97Sdan **       the INSERT change are as if the row was inserted by change A and then
57929e03e97Sdan **       updated according to change B.
58029e03e97Sdan **   <tr><td>INSERT <td>DELETE <td>
58129e03e97Sdan **       No change at all is copied into the output changeset.
58229e03e97Sdan **   <tr><td>UPDATE <td>INSERT <td>
58329e03e97Sdan **       Change A is copied into the output changeset. Change B is discarded.
58429e03e97Sdan **       This case does not occur if changeset B is recorded immediately after
58529e03e97Sdan **       changeset A.
58629e03e97Sdan **   <tr><td>UPDATE <td>UPDATE <td>
58729e03e97Sdan **       A single UPDATE is copied into the output changeset. The accompanying
58829e03e97Sdan **       values are as if the row was updated once by change A and then again
58929e03e97Sdan **       by change B.
59029e03e97Sdan **   <tr><td>UPDATE <td>DELETE <td>
59129e03e97Sdan **       A single DELETE is copied into the output changeset.
59229e03e97Sdan **   <tr><td>DELETE <td>INSERT <td>
59329e03e97Sdan **       If one or more of the column values in the row inserted by change
59429e03e97Sdan **       B differ from those in the row deleted by change A, an UPDATE
59529e03e97Sdan **       change is added to the output changeset. Otherwise, if the inserted
59629e03e97Sdan **       row is exactly the same as the deleted row, no change is added to
59729e03e97Sdan **       the output changeset.
59829e03e97Sdan **   <tr><td>DELETE <td>UPDATE <td>
59929e03e97Sdan **       Change A is copied into the output changeset. Change B is discarded.
60029e03e97Sdan **       This case does not occur if changeset B is recorded immediately after
60129e03e97Sdan **       changeset A.
60229e03e97Sdan **   <tr><td>DELETE <td>DELETE <td>
60329e03e97Sdan **       Change A is copied into the output changeset. Change B is discarded.
60429e03e97Sdan **       This case does not occur if changeset B is recorded immediately after
60529e03e97Sdan **       changeset A.
60629e03e97Sdan ** </table>
60729e03e97Sdan **
60829e03e97Sdan ** If the two changesets contain changes to the same table, then the number
60929e03e97Sdan ** of columns and the position of the primary key columns for the table must
61029e03e97Sdan ** be the same in each changeset. If this is not the case, attempting to
61129e03e97Sdan ** concatenate the two changesets together fails and this function returns
61229e03e97Sdan ** SQLITE_SCHEMA. If either of the two input changesets appear to be corrupt,
61329e03e97Sdan ** and the corruption is detected, SQLITE_CORRUPT is returned. Or, if an
61429e03e97Sdan ** out-of-memory condition occurs during processing, this function returns
61529e03e97Sdan ** SQLITE_NOMEM.
61629e03e97Sdan **
61729e03e97Sdan ** If none of the above errors occur, SQLITE_OK is returned and *ppOut set
61829e03e97Sdan ** to point to a buffer containing the output changeset. It is the
61929e03e97Sdan ** responsibility of the caller to eventually call sqlite3_free() on *ppOut
62029e03e97Sdan ** to release memory allocated for the buffer. *pnOut is set to the number
62129e03e97Sdan ** of bytes in the output changeset. If an error does occur, both *ppOut and
62229e03e97Sdan ** *pnOut are set to zero before returning.
6236cda207fSdan */
6245d607a6eSdan int sqlite3changeset_concat(
62529e03e97Sdan   int nA,                         /* Number of bytes in buffer pA */
62629e03e97Sdan   void *pA,                       /* Pointer to buffer containing changeset A */
62729e03e97Sdan   int nB,                         /* Number of bytes in buffer pB */
62829e03e97Sdan   void *pB,                       /* Pointer to buffer containing changeset B */
62929e03e97Sdan   int *pnOut,                     /* OUT: Number of bytes in output changeset */
63029e03e97Sdan   void **ppOut                    /* OUT: Buffer containing output changeset */
6315d607a6eSdan );
6325d607a6eSdan 
633d5f0767cSdan /*
634a2df3d9fSdan ** CAPI3REF: Apply A Changeset To A Database
635a2df3d9fSdan **
6362635a3beSdan ** Apply a changeset to a database. This function attempts to update the
6372635a3beSdan ** "main" database attached to handle db with the changes found in the
6382635a3beSdan ** changeset passed via the second and third arguments.
6392635a3beSdan **
64040368988Sdan ** The fourth argument (xFilter) passed to this function is the "filter
64140368988Sdan ** callback". If it is not NULL, then for each table affected by at least one
64240368988Sdan ** change in the changeset, the filter callback is invoked with
64340368988Sdan ** the table name as the second argument, and a copy of the context pointer
64440368988Sdan ** passed as the sixth argument to this function as the first. If the "filter
64540368988Sdan ** callback" returns zero, then no attempt is made to apply any changes to
64640368988Sdan ** the table. Otherwise, if the return value is non-zero or the xFilter
64740368988Sdan ** argument to this function is NULL, all changes related to the table are
64840368988Sdan ** attempted.
64940368988Sdan **
65040368988Sdan ** For each table that is not excluded by the filter callback, this function
65140368988Sdan ** tests that the target database contains a compatible table. A table is
65240368988Sdan ** considered compatible if all of the following are true:
6532635a3beSdan **
6542635a3beSdan ** <ul>
6552635a3beSdan **   <li> The table has the same name as the name recorded in the
6562635a3beSdan **        changeset, and
6572635a3beSdan **   <li> The table has the same number of columns as recorded in the
6582635a3beSdan **        changeset, and
6592635a3beSdan **   <li> The table has primary key columns in the same position as
6602635a3beSdan **        recorded in the changeset.
6612635a3beSdan ** </ul>
6622635a3beSdan **
66340368988Sdan ** If there is no compatible table, it is not an error, but none of the
66440368988Sdan ** changes associated with the table are applied. A warning message is issued
66540368988Sdan ** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
66640368988Sdan ** one such warning is issued for each table in the changeset.
6672635a3beSdan **
66840368988Sdan ** For each change for which there is a compatible table, an attempt is made
66940368988Sdan ** to modify the table contents according to the UPDATE, INSERT or DELETE
67040368988Sdan ** change. If a change cannot be applied cleanly, the conflict handler
67140368988Sdan ** function passed as the fifth argument to sqlite3changeset_apply() may be
67240368988Sdan ** invoked. A description of exactly when the conflict handler is invoked for
67340368988Sdan ** each type of change is below.
6742635a3beSdan **
6752635a3beSdan ** Each time the conflict handler function is invoked, it must return one
6762635a3beSdan ** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or
6772635a3beSdan ** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
6782635a3beSdan ** if the second argument passed to the conflict handler is either
6792635a3beSdan ** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
6802635a3beSdan ** returns an illegal value, any changes already made are rolled back and
6812635a3beSdan ** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different
6822635a3beSdan ** actions are taken by sqlite3changeset_apply() depending on the value
6832635a3beSdan ** returned by each invocation of the conflict-handler function. Refer to
6842635a3beSdan ** the documentation for the three
6852635a3beSdan ** [SQLITE_CHANGESET_OMIT|available return values] for details.
6862635a3beSdan **
6872635a3beSdan ** <dl>
6882635a3beSdan ** <dt>DELETE Changes<dd>
6892635a3beSdan **   For each DELETE change, this function checks if the target database
6902635a3beSdan **   contains a row with the same primary key value (or values) as the
6912635a3beSdan **   original row values stored in the changeset. If it does, and the values
6922635a3beSdan **   stored in all non-primary key columns also match the values stored in
6932635a3beSdan **   the changeset the row is deleted from the target database.
6942635a3beSdan **
6952635a3beSdan **   If a row with matching primary key values is found, but one or more of
6962635a3beSdan **   the non-primary key fields contains a value different from the original
6972635a3beSdan **   row value stored in the changeset, the conflict-handler function is
6982635a3beSdan **   invoked with [SQLITE_CHANGESET_DATA] as the second argument.
6992635a3beSdan **
7002635a3beSdan **   If no row with matching primary key values is found in the database,
7012635a3beSdan **   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
7022635a3beSdan **   passed as the second argument.
7032635a3beSdan **
7042635a3beSdan **   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
7052635a3beSdan **   (which can only happen if a foreign key constraint is violated), the
7062635a3beSdan **   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
7072635a3beSdan **   passed as the second argument. This includes the case where the DELETE
7082635a3beSdan **   operation is attempted because an earlier call to the conflict handler
7092635a3beSdan **   function returned [SQLITE_CHANGESET_REPLACE].
7102635a3beSdan **
7112635a3beSdan ** <dt>INSERT Changes<dd>
7122635a3beSdan **   For each INSERT change, an attempt is made to insert the new row into
7132635a3beSdan **   the database.
7142635a3beSdan **
7152635a3beSdan **   If the attempt to insert the row fails because the database already
7162635a3beSdan **   contains a row with the same primary key values, the conflict handler
7172635a3beSdan **   function is invoked with the second argument set to
7182635a3beSdan **   [SQLITE_CHANGESET_CONFLICT].
7192635a3beSdan **
7202635a3beSdan **   If the attempt to insert the row fails because of some other constraint
7212635a3beSdan **   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is
7222635a3beSdan **   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
7232635a3beSdan **   This includes the case where the INSERT operation is re-attempted because
7242635a3beSdan **   an earlier call to the conflict handler function returned
7252635a3beSdan **   [SQLITE_CHANGESET_REPLACE].
7262635a3beSdan **
7272635a3beSdan ** <dt>UPDATE Changes<dd>
728a2df3d9fSdan **   For each UPDATE change, this function checks if the target database
7292635a3beSdan **   contains a row with the same primary key value (or values) as the
7302635a3beSdan **   original row values stored in the changeset. If it does, and the values
7312635a3beSdan **   stored in all non-primary key columns also match the values stored in
7322635a3beSdan **   the changeset the row is updated within the target database.
7332635a3beSdan **
7342635a3beSdan **   If a row with matching primary key values is found, but one or more of
7352635a3beSdan **   the non-primary key fields contains a value different from an original
7362635a3beSdan **   row value stored in the changeset, the conflict-handler function is
7372635a3beSdan **   invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
7382635a3beSdan **   UPDATE changes only contain values for non-primary key fields that are
7392635a3beSdan **   to be modified, only those fields need to match the original values to
7402635a3beSdan **   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
7412635a3beSdan **
7422635a3beSdan **   If no row with matching primary key values is found in the database,
7432635a3beSdan **   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
7442635a3beSdan **   passed as the second argument.
7452635a3beSdan **
7462635a3beSdan **   If the UPDATE operation is attempted, but SQLite returns
7472635a3beSdan **   SQLITE_CONSTRAINT, the conflict-handler function is invoked with
7482635a3beSdan **   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
7492635a3beSdan **   This includes the case where the UPDATE operation is attempted after
7502635a3beSdan **   an earlier call to the conflict handler function returned
7512635a3beSdan **   [SQLITE_CHANGESET_REPLACE].
7522635a3beSdan ** </dl>
753d5f0767cSdan **
754d5f0767cSdan ** It is safe to execute SQL statements, including those that write to the
755d5f0767cSdan ** table that the callback related to, from within the xConflict callback.
756d5f0767cSdan ** This can be used to further customize the applications conflict
757d5f0767cSdan ** resolution strategy.
7582635a3beSdan **
7592635a3beSdan ** All changes made by this function are enclosed in a savepoint transaction.
7602635a3beSdan ** If any other error (aside from a constraint failure when attempting to
7612635a3beSdan ** write to the target database) occurs, then the savepoint transaction is
7622635a3beSdan ** rolled back, restoring the target database to its original state, and an
7632635a3beSdan ** SQLite error code returned.
764d5f0767cSdan */
765d5f0767cSdan int sqlite3changeset_apply(
766296c7658Sdan   sqlite3 *db,                    /* Apply change to "main" db of this handle */
767296c7658Sdan   int nChangeset,                 /* Size of changeset in bytes */
768296c7658Sdan   void *pChangeset,               /* Changeset blob */
76940368988Sdan   int(*xFilter)(
77040368988Sdan     void *pCtx,                   /* Copy of sixth arg to _apply() */
77140368988Sdan     const char *zTab              /* Table name */
77240368988Sdan   ),
773d5f0767cSdan   int(*xConflict)(
77440368988Sdan     void *pCtx,                   /* Copy of sixth arg to _apply() */
775d5f0767cSdan     int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
776d5f0767cSdan     sqlite3_changeset_iter *p     /* Handle describing change and conflict */
777d5f0767cSdan   ),
778296c7658Sdan   void *pCtx                      /* First argument passed to xConflict */
779d5f0767cSdan );
780d5f0767cSdan 
7810c698471Sdan /*
782157546f4Sshaneh ** CAPI3REF: Constants Passed To The Conflict Handler
783a2df3d9fSdan **
7842635a3beSdan ** Values that may be passed as the second argument to a conflict-handler.
7850c698471Sdan **
7862635a3beSdan ** <dl>
7872635a3beSdan ** <dt>SQLITE_CHANGESET_DATA<dd>
7880c698471Sdan **   The conflict handler is invoked with CHANGESET_DATA as the second argument
7890c698471Sdan **   when processing a DELETE or UPDATE change if a row with the required
7900c698471Sdan **   PRIMARY KEY fields is present in the database, but one or more other
7910c698471Sdan **   (non primary-key) fields modified by the update do not contain the
7920c698471Sdan **   expected "before" values.
7930c698471Sdan **
7940c698471Sdan **   The conflicting row, in this case, is the database row with the matching
7950c698471Sdan **   primary key.
7960c698471Sdan **
7972635a3beSdan ** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
7980c698471Sdan **   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
7990c698471Sdan **   argument when processing a DELETE or UPDATE change if a row with the
8000c698471Sdan **   required PRIMARY KEY fields is not present in the database.
8010c698471Sdan **
8020c698471Sdan **   There is no conflicting row in this case. The results of invoking the
8030c698471Sdan **   sqlite3changeset_conflict() API are undefined.
8040c698471Sdan **
8052635a3beSdan ** <dt>SQLITE_CHANGESET_CONFLICT<dd>
8060c698471Sdan **   CHANGESET_CONFLICT is passed as the second argument to the conflict
8072635a3beSdan **   handler while processing an INSERT change if the operation would result
8082635a3beSdan **   in duplicate primary key values.
8090c698471Sdan **
8100c698471Sdan **   The conflicting row in this case is the database row with the matching
8110c698471Sdan **   primary key.
8120c698471Sdan **
8132635a3beSdan ** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
8140c698471Sdan **   If any other constraint violation occurs while applying a change (i.e.
8150c698471Sdan **   a FOREIGN KEY, UNIQUE, CHECK or NOT NULL constraint), the conflict
8160c698471Sdan **   handler is invoked with CHANGESET_CONSTRAINT as the second argument.
8170c698471Sdan **
8180c698471Sdan **   There is no conflicting row in this case. The results of invoking the
8190c698471Sdan **   sqlite3changeset_conflict() API are undefined.
8202635a3beSdan ** </dl>
8210c698471Sdan */
822d5f0767cSdan #define SQLITE_CHANGESET_DATA       1
823d5f0767cSdan #define SQLITE_CHANGESET_NOTFOUND   2
824d5f0767cSdan #define SQLITE_CHANGESET_CONFLICT   3
825d5f0767cSdan #define SQLITE_CHANGESET_CONSTRAINT 4
826d5f0767cSdan 
8270c698471Sdan /*
828a2df3d9fSdan ** CAPI3REF: Constants Returned By The Conflict Handler
829a2df3d9fSdan **
830a2df3d9fSdan ** A conflict handler callback must return one of the following three values.
8310c698471Sdan **
8322635a3beSdan ** <dl>
8332635a3beSdan ** <dt>SQLITE_CHANGESET_OMIT<dd>
8340c698471Sdan **   If a conflict handler returns this value no special action is taken. The
8352635a3beSdan **   change that caused the conflict is not applied. The session module
8362635a3beSdan **   continues to the next change in the changeset.
8370c698471Sdan **
8382635a3beSdan ** <dt>SQLITE_CHANGESET_REPLACE<dd>
8390c698471Sdan **   This value may only be returned if the second argument to the conflict
8400c698471Sdan **   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
8410c698471Sdan **   is not the case, any changes applied so far are rolled back and the
8420c698471Sdan **   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
8430c698471Sdan **
8440c698471Sdan **   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
8450c698471Sdan **   handler, then the conflicting row is either updated or deleted, depending
8460c698471Sdan **   on the type of change.
8470c698471Sdan **
8480c698471Sdan **   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
8490c698471Sdan **   handler, then the conflicting row is removed from the database and a
8500c698471Sdan **   second attempt to apply the change is made. If this second attempt fails,
8510c698471Sdan **   the original row is restored to the database before continuing.
8520c698471Sdan **
8532635a3beSdan ** <dt>SQLITE_CHANGESET_ABORT<dd>
8540c698471Sdan **   If this value is returned, any changes applied so far are rolled back
8552635a3beSdan **   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
8562635a3beSdan ** </dl>
8570c698471Sdan */
858d5f0767cSdan #define SQLITE_CHANGESET_OMIT       0
859d5f0767cSdan #define SQLITE_CHANGESET_REPLACE    1
860d5f0767cSdan #define SQLITE_CHANGESET_ABORT      2
86191ddd559Sdan 
86236828bd9Sdrh /*
86336828bd9Sdrh ** Make sure we can call this stuff from C++.
86436828bd9Sdrh */
86536828bd9Sdrh #ifdef __cplusplus
86636828bd9Sdrh }
8674fccf43aSdan #endif
8684fccf43aSdan 
86936828bd9Sdrh #endif  /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
870