2011-03-08 19:22:50 +00:00
2016-05-04 21:06:21 +00:00
# if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
2011-03-08 19:22:50 +00:00
# define __SQLITESESSION_H_ 1
/*
* * Make sure we can call this stuff from C + + .
*/
# ifdef __cplusplus
extern " C " {
# endif
# include "sqlite3.h"
2011-03-20 11:20:41 +00:00
/*
* * CAPI3REF : Session Object Handle
2018-02-28 22:21:29 +00:00
* *
* * An instance of this object is a [ session ] that can be used to
* * record changes to a database .
2011-03-20 11:20:41 +00:00
*/
2011-03-08 19:22:50 +00:00
typedef struct sqlite3_session sqlite3_session ;
2011-03-20 11:20:41 +00:00
/*
* * CAPI3REF : Changeset Iterator Handle
2018-02-28 22:21:29 +00:00
* *
2018-03-01 18:09:02 +00:00
* * An instance of this object acts as a cursor for iterating
2018-02-28 22:21:29 +00:00
* * over the elements of a [ changeset ] or [ patchset ] .
2011-03-20 11:20:41 +00:00
*/
2011-03-08 19:22:50 +00:00
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter ;
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Create A New Session Object
2018-02-28 22:21:29 +00:00
* * CONSTRUCTOR : sqlite3_session
2011-03-20 11:20:41 +00:00
* *
2011-03-16 19:59:18 +00:00
* * 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
2011-03-18 13:05:15 +00:00
* * error code ( e . g . SQLITE_NOMEM ) is returned .
2011-03-16 19:59:18 +00:00
* *
* * It is possible to create multiple session objects attached to a single
* * database handle .
* *
* * Session objects created using this function should be deleted using the
* * [ sqlite3session_delete ( ) ] function before the database handle that they
* * are attached to is itself closed . If the database handle is closed before
* * the session object is deleted , then the results of calling any session
* * module function , including [ sqlite3session_delete ( ) ] on the session object
* * are undefined .
* *
* * Because the session module uses the [ sqlite3_preupdate_hook ( ) ] API , it
* * is not possible for an application to register a pre - update hook on a
* * database handle that has one or more session objects attached . Nor is
* * it possible to create a session object attached to a database handle for
* * which a pre - update hook is already defined . The results of attempting
* * either of these things are undefined .
* *
* * The session object will be used to create changesets for tables in
* * database zDb , where zDb is either " main " , or " temp " , or the name of an
2011-03-24 16:04:54 +00:00
* * attached database . It is not an error if database zDb is not attached
2011-03-16 19:59:18 +00:00
* * to the database when the session object is created .
2011-03-08 19:22:50 +00:00
*/
int sqlite3session_create (
sqlite3 * db , /* Database handle */
const char * zDb , /* Name of db (e.g. "main") */
sqlite3_session * * ppSession /* OUT: New session object */
) ;
2011-03-16 19:59:18 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Delete A Session Object
2018-02-28 22:21:29 +00:00
* * DESTRUCTOR : sqlite3_session
2011-03-20 11:20:41 +00:00
* *
2011-03-16 19:59:18 +00:00
* * Delete a session object previously allocated using
* * [ sqlite3session_create ( ) ] . Once a session object has been deleted , the
* * results of attempting to use pSession with any other session module
* * function are undefined .
* *
* * Session objects must be deleted before the database handle to which they
* * are attached is closed . Refer to the documentation for
* * [ sqlite3session_create ( ) ] for details .
*/
void sqlite3session_delete ( sqlite3_session * pSession ) ;
2021-04-22 17:40:28 +00:00
/*
2023-05-01 15:59:20 +00:00
* * CAPI3REF : Configure a Session Object
2021-04-22 17:40:28 +00:00
* * METHOD : sqlite3_session
2021-04-22 18:52:36 +00:00
* *
* * This method is used to configure a session object after it has been
2023-05-01 15:59:20 +00:00
* * created . At present the only valid values for the second parameter are
* * [ SQLITE_SESSION_OBJCONFIG_SIZE ] and [ SQLITE_SESSION_OBJCONFIG_ROWID ] .
2021-04-29 19:30:35 +00:00
* *
2023-05-01 15:59:20 +00:00
*/
int sqlite3session_object_config ( sqlite3_session * , int op , void * pArg ) ;
/*
* * CAPI3REF : Options for sqlite3session_object_config
2021-04-22 17:40:28 +00:00
* *
2023-05-01 15:59:20 +00:00
* * The following values may passed as the the 2 nd parameter to
2021-04-29 19:30:35 +00:00
* * sqlite3session_object_config ( ) .
2021-04-22 17:40:28 +00:00
* *
* * < dt > SQLITE_SESSION_OBJCONFIG_SIZE < dd >
* * This option is used to set , clear or query the flag that enables
* * the [ sqlite3session_changeset_size ( ) ] API . Because it imposes some
* * computational overhead , this API is disabled by default . Argument
* * pArg must point to a value of type ( int ) . If the value is initially
* * 0 , then the sqlite3session_changeset_size ( ) API is disabled . If it
* * is greater than 0 , then the same API is enabled . Or , if the initial
* * value is less than zero , no change is made . In all cases the ( int )
* * variable is set to 1 if the sqlite3session_changeset_size ( ) API is
* * enabled following the current call , or 0 otherwise .
* *
* * It is an error ( SQLITE_MISUSE ) to attempt to modify this setting after
* * the first table has been attached to the session object .
2023-04-24 19:22:21 +00:00
* *
* * < dt > SQLITE_SESSION_OBJCONFIG_ROWID < dd >
* * This option is used to set , clear or query the flag that enables
* * collection of data for tables with no explicit PRIMARY KEY .
* *
* * Normally , tables with no explicit PRIMARY KEY are simply ignored
* * by the sessions module . However , if this flag is set , it behaves
* * as if such tables have a column " _rowid_ INTEGER PRIMARY KEY " inserted
* * as their leftmost columns .
* *
* * It is an error ( SQLITE_MISUSE ) to attempt to modify this setting after
* * the first table has been attached to the session object .
2021-04-22 17:40:28 +00:00
*/
2023-04-24 19:22:21 +00:00
# define SQLITE_SESSION_OBJCONFIG_SIZE 1
# define SQLITE_SESSION_OBJCONFIG_ROWID 2
2013-08-23 17:43:32 +00:00
2011-03-08 19:22:50 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Enable Or Disable A Session Object
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2011-03-20 11:20:41 +00:00
* *
2011-03-08 19:22:50 +00:00
* * 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 .
2011-03-18 13:05:15 +00:00
* * Refer to the documentation for [ sqlite3session_changeset ( ) ] for further
* * details regarding how enabling and disabling a session object affects
* * the eventual changesets .
2011-03-08 19:22:50 +00:00
* *
* * Passing zero to this function disables the session . Passing a value
* * greater than zero enables it . Passing a value less than zero is a
* * no - op , and may be used to query the current state of the session .
* *
* * The return value indicates the final state of the session object : 0 if
* * the session is disabled , or 1 if it is enabled .
*/
int sqlite3session_enable ( sqlite3_session * pSession , int bEnable ) ;
2011-03-23 16:03:11 +00:00
/*
* * CAPI3REF : Set Or Clear the Indirect Change Flag
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2011-03-23 16:03:11 +00:00
* *
* * Each change recorded by a session object is marked as either direct or
* * indirect . A change is marked as indirect if either :
* *
* * < ul >
* * < li > The session object " indirect " flag is set when the change is
* * made , or
* * < li > The change is made by an SQL trigger or foreign key action
* * instead of directly as a result of a users SQL statement .
* * < / ul >
* *
* * If a single row is affected by more than one operation within a session ,
* * then the change is considered indirect if all operations meet the criteria
* * for an indirect change above , or direct otherwise .
* *
* * This function is used to set , clear or query the session object indirect
* * flag . If the second argument passed to this function is zero , then the
* * indirect flag is cleared . If it is greater than zero , the indirect flag
* * is set . Passing a value less than zero does not modify the current value
* * of the indirect flag , and may be used to query the current state of the
* * indirect flag for the specified session object .
* *
* * The return value indicates the final state of the indirect flag : 0 if
* * it is clear , or 1 if it is set .
*/
int sqlite3session_indirect ( sqlite3_session * pSession , int bIndirect ) ;
2011-03-08 19:22:50 +00:00
/*
2011-03-22 02:03:23 +00:00
* * CAPI3REF : Attach A Table To A Session Object
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2011-03-20 11:20:41 +00:00
* *
2011-03-22 15:21:03 +00:00
* * If argument zTab is not NULL , then it is the name of a table to attach
* * to the session object passed as the first argument . All subsequent changes
* * made to the table while the session object is enabled will be recorded . See
* * documentation for [ sqlite3session_changeset ( ) ] for further details .
* *
* * Or , if argument zTab is NULL , then changes are recorded for all tables
* * in the database . If additional tables are added to the database ( by
* * executing " CREATE TABLE " statements ) after this call is made , changes for
* * the new tables are also recorded .
2011-03-08 19:22:50 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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 .
* *
2011-03-21 11:55:06 +00:00
* * Changes are not recorded for individual rows that have NULL values stored
* * in one or more of their PRIMARY KEY columns .
* *
2011-03-22 15:21:03 +00:00
* * SQLITE_OK is returned if the call completes without error . Or , if an error
* * occurs , an SQLite error code ( e . g . SQLITE_NOMEM ) is returned .
2018-01-18 16:53:41 +00:00
* *
* * < h3 > Special sqlite_stat1 Handling < / h3 >
* *
2018-01-18 16:56:19 +00:00
* * As of SQLite version 3.22 .0 , the " sqlite_stat1 " table is an exception to
* * some of the rules above . In SQLite , the schema of sqlite_stat1 is :
2018-01-18 16:53:41 +00:00
* * < pre >
* * & nbsp ; CREATE TABLE sqlite_stat1 ( tbl , idx , stat )
* * < / pre >
* *
* * Even though sqlite_stat1 does not have a PRIMARY KEY , changes are
* * recorded for it as if the PRIMARY KEY is ( tbl , idx ) . Additionally , changes
* * are recorded for rows for which ( idx IS NULL ) is true . However , for such
* * rows a zero - length blob ( SQL value X ' ' ) is stored in the changeset or
* * patchset instead of a NULL value . This allows such changesets to be
* * manipulated by legacy implementations of sqlite3changeset_invert ( ) ,
* * concat ( ) and similar .
* *
* * The sqlite3changeset_apply ( ) function automatically converts the
* * zero - length blob back to a NULL value when updating the sqlite_stat1
* * table . However , if the application calls sqlite3changeset_new ( ) ,
* * sqlite3changeset_old ( ) or sqlite3changeset_conflict on a changeset
* * iterator directly ( including on a changeset iterator passed to a
* * conflict - handler callback ) then the X ' ' value is returned . The application
* * must translate X ' ' to NULL itself if required .
2018-01-18 16:56:19 +00:00
* *
* * Legacy ( older than 3.22 .0 ) versions of the sessions module cannot capture
* * changes made to the sqlite_stat1 table . Legacy versions of the
* * sqlite3changeset_apply ( ) function silently ignore any modifications to the
* * sqlite_stat1 table that are part of a changeset or patchset .
2011-03-08 19:22:50 +00:00
*/
int sqlite3session_attach (
sqlite3_session * pSession , /* Session object */
const char * zTab /* Table name */
) ;
2013-08-23 17:43:32 +00:00
/*
* * CAPI3REF : Set a table filter on a Session Object .
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2013-08-23 17:43:32 +00:00
* *
* * The second argument ( xFilter ) is the " filter callback " . For changes to rows
2016-09-28 16:04:22 +00:00
* * in tables that are not attached to the Session object , the filter is called
2013-08-23 17:43:32 +00:00
* * to determine whether changes to the table ' s rows should be tracked or not .
2019-11-26 14:24:12 +00:00
* * If xFilter returns 0 , changes are not tracked . Note that once a table is
2013-08-23 17:43:32 +00:00
* * attached , xFilter will not be called again .
*/
void sqlite3session_table_filter (
sqlite3_session * pSession , /* Session object */
int ( * xFilter ) (
void * pCtx , /* Copy of third arg to _filter_table() */
const char * zTab /* Table name */
) ,
void * pCtx /* First argument passed to xFilter */
) ;
2011-03-08 19:22:50 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Generate A Changeset From A Session Object
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2011-03-20 11:20:41 +00:00
* *
2011-03-16 19:59:18 +00:00
* * Obtain a changeset containing changes to the tables attached to the
* * session object passed as the first argument . If successful ,
* * set * ppChangeset to point to a buffer containing the changeset
* * and * pnChangeset to the size of the changeset in bytes before returning
* * SQLITE_OK . If an error occurs , set both * ppChangeset and * pnChangeset to
* * zero and return an SQLite error code .
2011-03-08 19:22:50 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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 .
* *
2011-03-21 11:55:06 +00:00
* * Changes are not recorded for rows that have NULL values stored in one or
* * more of their PRIMARY KEY columns . If such a row is inserted or deleted ,
* * no corresponding change is present in the changesets returned by this
* * function . If an existing row with one or more NULL values stored in
* * PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non - NULL ,
* * only an INSERT is appears in the changeset . Similarly , if an existing row
* * with non - NULL PRIMARY KEY values is updated so that one or more of its
* * PRIMARY KEY columns are set to NULL , the resulting changeset contains a
* * DELETE change only .
* *
2011-03-18 13:05:15 +00:00
* * The contents of a changeset may be traversed using an iterator created
* * using the [ sqlite3changeset_start ( ) ] API . A changeset may be applied to
2011-03-20 11:20:41 +00:00
* * a database with a compatible schema using the [ sqlite3changeset_apply ( ) ]
2011-03-18 13:05:15 +00:00
* * API .
* *
2015-10-01 16:35:57 +00:00
* * Within a changeset generated by this function , all changes related to a
* * single table are grouped together . In other words , when iterating through
* * a changeset or when applying a changeset to a database , all changes related
* * to a single table are processed before moving on to the next table . Tables
* * are sorted in the same order in which they were attached ( or auto - attached )
* * to the sqlite3_session object . The order in which the changes related to
* * a single table are stored is undefined .
* *
2011-03-16 19:59:18 +00:00
* * 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 ( ) ] .
2011-03-18 13:05:15 +00:00
* *
2011-03-20 11:20:41 +00:00
* * < h3 > Changeset Generation < / h3 >
2011-03-18 13:05:15 +00:00
* *
* * 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 .
* *
2011-03-21 11:55:06 +00:00
* * There is one exception to the previous paragraph : when a row is inserted ,
2011-03-22 02:03:23 +00:00
* * updated or deleted , if one or more of its primary key columns contain a
2011-03-21 11:55:06 +00:00
* * NULL value , no record of the change is made .
* *
2011-03-18 13:05:15 +00:00
* * 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
2011-03-22 02:03:23 +00:00
* * deleted while a session object is active , neither the insert nor the delete
2011-03-18 13:05:15 +00:00
* * 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 .
2011-03-08 19:22:50 +00:00
*/
int sqlite3session_changeset (
sqlite3_session * pSession , /* Session object */
int * pnChangeset , /* OUT: Size of buffer at *ppChangeset */
void * * ppChangeset /* OUT: Buffer containing changeset */
) ;
2021-04-21 20:52:17 +00:00
/*
2021-04-22 18:52:36 +00:00
* * CAPI3REF : Return An Upper - limit For The Size Of The Changeset
2021-04-29 19:30:35 +00:00
* * METHOD : sqlite3_session
2021-04-21 20:52:17 +00:00
* *
2021-04-22 18:39:02 +00:00
* * By default , this function always returns 0. For it to return
* * a useful result , the sqlite3_session object must have been configured
2021-04-29 19:30:35 +00:00
* * to enable this API using sqlite3session_object_config ( ) with the
2021-04-22 18:39:02 +00:00
* * SQLITE_SESSION_OBJCONFIG_SIZE verb .
* *
* * When enabled , this function returns an upper limit , in bytes , for the size
* * of the changeset that might be produced if sqlite3session_changeset ( ) were
* * called . The final changeset size might be equal to or smaller than the
* * size in bytes returned by this function .
2021-04-21 20:52:17 +00:00
*/
sqlite3_int64 sqlite3session_changeset_size ( sqlite3_session * pSession ) ;
2015-04-08 16:01:12 +00:00
/*
2018-02-28 22:21:29 +00:00
* * CAPI3REF : Load The Difference Between Tables Into A Session
* * METHOD : sqlite3_session
2015-04-08 16:01:12 +00:00
* *
* * If it is not already attached to the session object passed as the first
* * argument , this function attaches table zTbl in the same manner as the
* * [ sqlite3session_attach ( ) ] function . If zTbl does not exist , or if it
* * does not have a primary key , this function is a no - op ( but does not return
* * an error ) .
* *
* * Argument zFromDb must be the name of a database ( " main " , " temp " etc . )
* * attached to the same database handle as the session object that contains
* * a table compatible with the table attached to the session by this function .
* * A table is considered compatible if it :
* *
* * < ul >
* * < li > Has the same name ,
* * < li > Has the same set of columns declared in the same order , and
* * < li > Has the same PRIMARY KEY definition .
* * < / ul >
* *
2015-04-23 17:22:49 +00:00
* * If the tables are not compatible , SQLITE_SCHEMA is returned . If the tables
* * are compatible but do not have any PRIMARY KEY columns , it is not an error
* * but no changes are added to the session object . As with other session
* * APIs , tables without PRIMARY KEYs are simply ignored .
* *
2015-04-08 16:01:12 +00:00
* * This function adds a set of changes to the session object that could be
* * used to update the table in database zFrom ( call this the " from-table " )
* * so that its content is the same as the table attached to the session
* * object ( call this the " to-table " ) . Specifically :
* *
* * < ul >
* * < li > For each row ( primary key ) that exists in the to - table but not in
* * the from - table , an INSERT record is added to the session object .
* *
* * < li > For each row ( primary key ) that exists in the to - table but not in
* * the from - table , a DELETE record is added to the session object .
* *
* * < li > For each row ( primary key ) that exists in both tables , but features
2017-02-04 17:33:30 +00:00
* * different non - PK values in each , an UPDATE record is added to the
* * session .
2015-04-08 16:01:12 +00:00
* * < / ul >
* *
* * To clarify , if this function is called and then a changeset constructed
* * using [ sqlite3session_changeset ( ) ] , then after applying that changeset to
* * database zFrom the contents of the two compatible tables would be
* * identical .
* *
* * It an error if database zFrom does not exist or does not contain the
* * required compatible table .
* *
2019-11-26 14:24:12 +00:00
* * If the operation is successful , SQLITE_OK is returned . Otherwise , an SQLite
2015-04-08 16:01:12 +00:00
* * error code . In this case , if argument pzErrMsg is not NULL , * pzErrMsg
* * may be set to point to a buffer containing an English language error
* * message . It is the responsibility of the caller to free this buffer using
* * sqlite3_free ( ) .
*/
int sqlite3session_diff (
sqlite3_session * pSession ,
const char * zFromDb ,
const char * zTbl ,
char * * pzErrMsg
) ;
2014-09-23 20:39:55 +00:00
2014-08-15 20:15:49 +00:00
/*
* * CAPI3REF : Generate A Patchset From A Session Object
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_session
2014-08-16 19:01:00 +00:00
* *
* * The differences between a patchset and a changeset are that :
* *
* * < ul >
* * < li > DELETE records consist of the primary key fields only . The
* * original values of other fields are omitted .
* * < li > The original values of any modified fields are omitted from
* * UPDATE records .
* * < / ul >
* *
* * A patchset blob may be used with up to date versions of all
* * sqlite3changeset_xxx API functions except for sqlite3changeset_invert ( ) ,
* * which returns SQLITE_CORRUPT if it is passed a patchset . Similarly ,
* * attempting to use a patchset blob with old versions of the
* * sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error .
* *
* * Because the non - primary key " old.* " fields are omitted , no
* * SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
* * is passed to the sqlite3changeset_apply ( ) API . Other conflict types work
* * in the same way as for changesets .
2015-10-01 16:35:57 +00:00
* *
* * Changes within a patchset are ordered in the same way as for changesets
* * generated by the sqlite3session_changeset ( ) function ( i . e . all changes for
* * a single table are grouped together , tables appear in the order in which
* * they were attached to the session object ) .
2014-08-15 20:15:49 +00:00
*/
int sqlite3session_patchset (
sqlite3_session * pSession , /* Session object */
2017-10-04 16:35:01 +00:00
int * pnPatchset , /* OUT: Size of buffer at *ppPatchset */
void * * ppPatchset /* OUT: Buffer containing patchset */
2014-08-15 20:15:49 +00:00
) ;
2011-07-16 18:05:07 +00:00
/*
* * CAPI3REF : Test if a changeset has recorded any changes .
* *
* * Return non - zero if no changes to attached tables have been recorded by
* * the session object passed as the first argument . Otherwise , if one or
* * more changes have been recorded , return zero .
* *
* * Even if this function returns zero , it is possible that calling
* * [ sqlite3session_changeset ( ) ] on the session handle may still return a
* * changeset that contains no changes . This can happen when a row in
* * an attached table is modified and then later on the original values
* * are restored . However , if this function returns non - zero , then it is
* * guaranteed that a call to sqlite3session_changeset ( ) will return a
* * changeset containing zero changes .
*/
int sqlite3session_isempty ( sqlite3_session * pSession ) ;
2020-12-23 16:46:39 +00:00
/*
* * CAPI3REF : Query for the amount of heap memory used by a session object .
* *
* * This API returns the total amount of heap memory in bytes currently
* * used by the session object passed as the only argument .
*/
sqlite3_int64 sqlite3session_memory_used ( sqlite3_session * pSession ) ;
2011-03-08 19:22:50 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Create An Iterator To Traverse A Changeset
2018-02-28 22:21:29 +00:00
* * CONSTRUCTOR : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2011-03-08 19:22:50 +00:00
* * Create an iterator used to iterate through the contents of a changeset .
2011-03-18 13:05:15 +00:00
* * 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 .
2011-07-16 18:05:07 +00:00
* *
* * Assuming the changeset blob was created by one of the
* * [ sqlite3session_changeset ( ) ] , [ sqlite3changeset_concat ( ) ] or
2011-07-16 18:35:53 +00:00
* * [ sqlite3changeset_invert ( ) ] functions , all changes within the changeset
* * that apply to a single table are grouped together . This means that when
* * an application iterates through a changeset using an iterator created by
2016-09-28 16:05:53 +00:00
* * this function , all changes that relate to a single table are visited
2011-07-16 18:35:53 +00:00
* * consecutively . There is no chance that the iterator will visit a change
* * the applies to table X , then one for table Y , and then later on visit
* * another change for table X .
2018-10-20 13:48:09 +00:00
* *
* * The behavior of sqlite3changeset_start_v2 ( ) and its streaming equivalent
* * may be modified by passing a combination of
* * [ SQLITE_CHANGESETSTART_INVERT | supported flags ] as the 4 th parameter .
* *
* * Note that the sqlite3changeset_start_v2 ( ) API is still < b > experimental < / b >
* * and therefore subject to change .
2011-03-08 19:22:50 +00:00
*/
int sqlite3changeset_start (
2011-03-18 13:05:15 +00:00
sqlite3_changeset_iter * * pp , /* OUT: New changeset iterator handle */
int nChangeset , /* Size of changeset blob in bytes */
void * pChangeset /* Pointer to blob containing changeset */
2011-03-08 19:22:50 +00:00
) ;
2018-10-20 13:48:09 +00:00
int sqlite3changeset_start_v2 (
sqlite3_changeset_iter * * pp , /* OUT: New changeset iterator handle */
int nChangeset , /* Size of changeset blob in bytes */
void * pChangeset , /* Pointer to blob containing changeset */
int flags /* SESSION_CHANGESETSTART_* flags */
) ;
/*
* * CAPI3REF : Flags for sqlite3changeset_start_v2
* *
* * The following flags may passed via the 4 th parameter to
* * [ sqlite3changeset_start_v2 ] and [ sqlite3changeset_start_v2_strm ] :
* *
* * < dt > SQLITE_CHANGESETAPPLY_INVERT < dd >
* * Invert the changeset while iterating through it . This is equivalent to
* * inverting a changeset using sqlite3changeset_invert ( ) before applying it .
* * It is an error to specify this flag with a patchset .
*/
# define SQLITE_CHANGESETSTART_INVERT 0x0002
2011-03-08 19:22:50 +00:00
2014-09-23 20:39:55 +00:00
2011-03-08 19:22:50 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Advance A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2019-11-26 14:24:12 +00:00
* * This function may only be used with iterators created by the function
2011-03-18 13:05:15 +00:00
* * [ 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 .
* *
* * 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 .
2011-03-08 19:22:50 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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 .
2011-03-08 19:22:50 +00:00
*/
int sqlite3changeset_next ( sqlite3_changeset_iter * pIter ) ;
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Obtain The Current Operation From A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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
2011-03-21 07:23:09 +00:00
* * call to [ sqlite3changeset_next ( ) ] must have returned [ SQLITE_ROW ] . If this
* * is not the case , this function returns [ SQLITE_MISUSE ] .
2011-03-18 13:05:15 +00:00
* *
2021-03-12 00:44:10 +00:00
* * Arguments pOp , pnCol and pzTab may not be NULL . Upon return , three
* * outputs are set through these pointers :
* *
* * * 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 ;
* *
* * * pnCol is set to the number of columns in the table affected by the change ; and
* *
* * * 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 pbIndirect is not NULL , then * pbIndirect is set to true ( 1 ) if the change
2011-03-23 16:03:11 +00:00
* * is an indirect change , or false ( 0 ) otherwise . See the documentation for
* * [ sqlite3session_indirect ( ) ] for a description of direct and indirect
2021-03-12 00:44:10 +00:00
* * changes .
2011-03-18 13:05:15 +00:00
* *
* * 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 .
2011-03-08 19:22:50 +00:00
*/
int sqlite3changeset_op (
2011-03-15 16:37:27 +00:00
sqlite3_changeset_iter * pIter , /* Iterator object */
const char * * pzTab , /* OUT: Pointer to table name */
int * pnCol , /* OUT: Number of columns in table */
2011-03-23 16:03:11 +00:00
int * pOp , /* OUT: SQLITE_INSERT, DELETE or UPDATE */
int * pbIndirect /* OUT: True for an 'indirect' change */
2011-03-08 19:22:50 +00:00
) ;
2011-03-18 13:05:15 +00:00
2011-03-24 11:22:59 +00:00
/*
* * CAPI3REF : Obtain The Primary Key Definition Of A Table
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-24 11:22:59 +00:00
* *
* * For each modified table , a changeset includes the following :
* *
* * < ul >
* * < li > The number of columns in the table , and
* * < li > Which of those columns make up the tables PRIMARY KEY .
* * < / ul >
* *
* * This function is used to find which columns comprise the PRIMARY KEY of
* * the table modified by the change that iterator pIter currently points to .
* * If successful , * pabPK is set to point to an array of nCol entries , where
* * nCol is the number of columns in the table . Elements of * pabPK are set to
* * 0x01 if the corresponding column is part of the tables primary key , or
* * 0x00 if it is not .
* *
2016-09-28 16:04:22 +00:00
* * If argument pnCol is not NULL , then * pnCol is set to the number of columns
2011-03-24 11:22:59 +00:00
* * in the table .
* *
* * If this function is called when the iterator does not point to a valid
* * entry , SQLITE_MISUSE is returned and the output variables zeroed . Otherwise ,
* * SQLITE_OK is returned and the output variables populated as described
* * above .
*/
int sqlite3changeset_pk (
sqlite3_changeset_iter * pIter , /* Iterator object */
unsigned char * * pabPK , /* OUT: Array of boolean - true for PK cols */
int * pnCol /* OUT: Number of entries in output array */
) ;
2011-03-18 13:05:15 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Obtain old . * Values From A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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
2011-03-21 07:23:09 +00:00
* * currently points to is either [ SQLITE_DELETE ] or [ SQLITE_UPDATE ] . Otherwise ,
* * this function returns [ SQLITE_MISUSE ] and sets * ppValue to NULL .
2011-03-18 13:05:15 +00:00
* *
* * 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 ,
2011-03-21 07:23:09 +00:00
* * [ SQLITE_RANGE ] is returned and * ppValue is set to NULL .
2011-03-18 13:05:15 +00:00
* *
* * 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 .
*/
2011-03-08 19:22:50 +00:00
int sqlite3changeset_old (
2011-03-15 16:37:27 +00:00
sqlite3_changeset_iter * pIter , /* Changeset iterator */
int iVal , /* Column number */
sqlite3_value * * ppValue /* OUT: Old value (or NULL pointer) */
2011-03-08 19:22:50 +00:00
) ;
2011-03-18 13:05:15 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Obtain new . * Values From A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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
2011-03-21 07:23:09 +00:00
* * currently points to is either [ SQLITE_UPDATE ] or [ SQLITE_INSERT ] . Otherwise ,
* * this function returns [ SQLITE_MISUSE ] and sets * ppValue to NULL .
2011-03-18 13:05:15 +00:00
* *
* * 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 ,
2011-03-21 07:23:09 +00:00
* * [ SQLITE_RANGE ] is returned and * ppValue is set to NULL .
2011-03-18 13:05:15 +00:00
* *
* * 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 .
*/
2011-03-08 19:22:50 +00:00
int sqlite3changeset_new (
2011-03-15 16:37:27 +00:00
sqlite3_changeset_iter * pIter , /* Changeset iterator */
int iVal , /* Column number */
sqlite3_value * * ppValue /* OUT: New value (or NULL pointer) */
2011-03-08 19:22:50 +00:00
) ;
2011-03-15 16:37:27 +00:00
2011-03-11 19:05:52 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Obtain Conflicting Row Values From A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
2011-03-18 13:05:15 +00:00
* * This function should only be used with iterator objects passed to a
* * conflict - handler callback by [ sqlite3changeset_apply ( ) ] with either
2011-03-21 07:23:09 +00:00
* * [ SQLITE_CHANGESET_DATA ] or [ SQLITE_CHANGESET_CONFLICT ] . If this function
* * is called on any other iterator , [ SQLITE_MISUSE ] is returned and * ppValue
2011-03-18 13:05:15 +00:00
* * is set to NULL .
2011-03-11 19:05:52 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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 ,
2011-03-21 07:23:09 +00:00
* * [ SQLITE_RANGE ] is returned and * ppValue is set to NULL .
2011-03-18 13:05:15 +00:00
* *
* * 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 .
2011-03-11 19:05:52 +00:00
*/
int sqlite3changeset_conflict (
2011-03-15 16:37:27 +00:00
sqlite3_changeset_iter * pIter , /* Changeset iterator */
int iVal , /* Column number */
2011-03-11 19:05:52 +00:00
sqlite3_value * * ppValue /* OUT: Value from conflicting row */
) ;
2013-07-03 19:53:05 +00:00
/*
* * CAPI3REF : Determine The Number Of Foreign Key Constraint Violations
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2013-07-03 19:53:05 +00:00
* *
* * This function may only be called with an iterator passed to an
* * SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback . In this case
* * it sets the output variable to the total number of known foreign key
* * violations in the destination database and returns SQLITE_OK .
* *
* * In all other cases this function returns SQLITE_MISUSE .
*/
int sqlite3changeset_fk_conflicts (
sqlite3_changeset_iter * pIter , /* Changeset iterator */
int * pnOut /* OUT: Number of FK violations */
) ;
2011-03-08 19:22:50 +00:00
/*
2011-03-22 02:03:23 +00:00
* * CAPI3REF : Finalize A Changeset Iterator
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changeset_iter
2011-03-20 11:20:41 +00:00
* *
* * This function is used to finalize an iterator allocated with
2011-03-21 07:23:09 +00:00
* * [ sqlite3changeset_start ( ) ] .
2011-03-08 19:22:50 +00:00
* *
2011-03-18 13:05:15 +00:00
* * 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
2011-03-21 07:23:09 +00:00
* * [ sqlite3changeset_apply ( ) ] , [ SQLITE_MISUSE ] is immediately returned and the
2011-03-18 13:05:15 +00:00
* * call has no effect .
* *
* * If an error was encountered within a call to an sqlite3changeset_xxx ( )
2011-03-21 07:23:09 +00:00
* * function ( for example an [ SQLITE_CORRUPT ] in [ sqlite3changeset_next ( ) ] or an
* * [ SQLITE_NOMEM ] in [ sqlite3changeset_new ( ) ] ) then an error code corresponding
2011-03-18 13:05:15 +00:00
* * to that error is returned by this function . Otherwise , SQLITE_OK is
* * returned . This is to allow the following pattern ( pseudo - code ) :
* *
2018-02-28 21:50:00 +00:00
* * < pre >
2011-03-18 13:05:15 +00:00
* * sqlite3changeset_start ( ) ;
* * while ( SQLITE_ROW = = sqlite3changeset_next ( ) ) {
* * // Do something with change.
* * }
* * rc = sqlite3changeset_finalize ( ) ;
* * if ( rc ! = SQLITE_OK ) {
* * // An error has occurred
* * }
2018-02-28 21:50:00 +00:00
* * < / pre >
2011-03-08 19:22:50 +00:00
*/
int sqlite3changeset_finalize ( sqlite3_changeset_iter * pIter ) ;
2011-03-09 11:17:05 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Invert A Changeset
* *
2011-03-18 16:13:53 +00:00
* * This function is used to " invert " a changeset object . Applying an inverted
* * changeset to a database reverses the effects of applying the uninverted
* * changeset . Specifically :
* *
* * < ul >
* * < li > Each DELETE change is changed to an INSERT , and
* * < li > Each INSERT change is changed to a DELETE , and
* * < li > For each UPDATE change , the old . * and new . * values are exchanged .
* * < / ul >
* *
2015-10-01 16:35:57 +00:00
* * This function does not change the order in which changes appear within
* * the changeset . It merely reverses the sense of each individual change .
* *
2011-03-18 16:13:53 +00:00
* * If successful , a pointer to a buffer containing the inverted changeset
* * is stored in * ppOut , the size of the same buffer is stored in * pnOut , and
* * SQLITE_OK is returned . If an error occurs , both * pnOut and * ppOut are
* * zeroed and an SQLite error code returned .
* *
* * It is the responsibility of the caller to eventually call sqlite3_free ( )
* * on the * ppOut pointer to free the buffer allocation following a successful
* * call to this function .
2011-03-25 10:52:01 +00:00
* *
* * WARNING / TODO : This function currently assumes that the input is a valid
* * changeset . If it is not , the results are undefined .
2011-03-09 11:17:05 +00:00
*/
int sqlite3changeset_invert (
2011-07-26 15:50:36 +00:00
int nIn , const void * pIn , /* Input changeset */
2011-03-09 11:17:05 +00:00
int * pnOut , void * * ppOut /* OUT: Inverse of input */
) ;
2011-04-14 18:01:41 +00:00
/*
2011-04-15 12:04:50 +00:00
* * CAPI3REF : Concatenate Two Changeset Objects
* *
* * This function is used to concatenate two changesets , A and B , into a
* * single changeset . The result is a changeset equivalent to applying
* * changeset A followed by changeset B .
* *
2015-06-11 17:26:10 +00:00
* * This function combines the two input changesets using an
* * sqlite3_changegroup object . Calling it produces similar results as the
* * following code fragment :
* *
2018-02-28 21:50:00 +00:00
* * < pre >
2015-06-11 17:26:10 +00:00
* * sqlite3_changegroup * pGrp ;
* * rc = sqlite3_changegroup_new ( & pGrp ) ;
* * if ( rc = = SQLITE_OK ) rc = sqlite3changegroup_add ( pGrp , nA , pA ) ;
* * if ( rc = = SQLITE_OK ) rc = sqlite3changegroup_add ( pGrp , nB , pB ) ;
* * if ( rc = = SQLITE_OK ) {
* * rc = sqlite3changegroup_output ( pGrp , pnOut , ppOut ) ;
* * } else {
* * * ppOut = 0 ;
* * * pnOut = 0 ;
* * }
2018-02-28 21:50:00 +00:00
* * < / pre >
2011-04-15 12:04:50 +00:00
* *
2015-06-11 17:26:10 +00:00
* * Refer to the sqlite3_changegroup documentation below for details .
*/
int sqlite3changeset_concat (
int nA , /* Number of bytes in buffer pA */
void * pA , /* Pointer to buffer containing changeset A */
int nB , /* Number of bytes in buffer pB */
void * pB , /* Pointer to buffer containing changeset B */
int * pnOut , /* OUT: Number of bytes in output changeset */
void * * ppOut /* OUT: Buffer containing output changeset */
) ;
2023-10-04 21:15:24 +00:00
/*
* * CAPI3REF : Upgrade the Schema of a Changeset / Patchset
*/
int sqlite3changeset_upgrade (
sqlite3 * db ,
const char * zDb ,
int nIn , const void * pIn , /* Input changeset */
int * pnOut , void * * ppOut /* OUT: Inverse of input */
) ;
2015-06-11 17:26:10 +00:00
/*
2016-08-27 18:35:55 +00:00
* * CAPI3REF : Changegroup Handle
2018-02-28 22:21:29 +00:00
* *
* * A changegroup is an object used to combine two or more
* * [ changesets ] or [ patchsets ]
2015-06-11 17:26:10 +00:00
*/
typedef struct sqlite3_changegroup sqlite3_changegroup ;
/*
2016-08-27 18:35:55 +00:00
* * CAPI3REF : Create A New Changegroup Object
2018-02-28 22:21:29 +00:00
* * CONSTRUCTOR : sqlite3_changegroup
2015-06-11 17:26:10 +00:00
* *
* * An sqlite3_changegroup object is used to combine two or more changesets
* * ( or patchsets ) into a single changeset ( or patchset ) . A single changegroup
* * object may combine changesets or patchsets , but not both . The output is
* * always in the same format as the input .
* *
* * If successful , this function returns SQLITE_OK and populates ( * pp ) with
* * a pointer to a new sqlite3_changegroup object before returning . The caller
* * should eventually free the returned object using a call to
* * sqlite3changegroup_delete ( ) . If an error occurs , an SQLite error code
* * ( i . e . SQLITE_NOMEM ) is returned and * pp is set to NULL .
* *
* * The usual usage pattern for an sqlite3_changegroup object is as follows :
* *
* * < ul >
* * < li > It is created using a call to sqlite3changegroup_new ( ) .
* *
* * < li > Zero or more changesets ( or patchsets ) are added to the object
* * by calling sqlite3changegroup_add ( ) .
* *
* * < li > The result of combining all input changesets together is obtained
* * by the application via a call to sqlite3changegroup_output ( ) .
* *
* * < li > The object is deleted using a call to sqlite3changegroup_delete ( ) .
* * < / ul >
* *
* * Any number of calls to add ( ) and output ( ) may be made between the calls to
* * new ( ) and delete ( ) , and in any order .
* *
* * As well as the regular sqlite3changegroup_add ( ) and
* * sqlite3changegroup_output ( ) functions , also available are the streaming
* * versions sqlite3changegroup_add_strm ( ) and sqlite3changegroup_output_strm ( ) .
*/
int sqlite3changegroup_new ( sqlite3_changegroup * * pp ) ;
2023-10-04 21:15:24 +00:00
/*
* * CAPI3REF : Add a Schema to a Changegroup
* * METHOD : sqlite3_changegroup_schema
* *
* * This method may be used to optionally enforce the rule that the changesets
* * added to the changegroup handle must match the schema of database zDb
* * ( " main " , " temp " , or the name of an attached database ) . If
* * sqlite3changegroup_add ( ) is called to add a changeset that is not compatible
* * with the configured schema , SQLITE_SCHEMA is returned and the changegroup
* * object is left in an undefined state .
* *
* * A changeset schema is considered compatible with the database schema in
* * the same way as for sqlite3changeset_apply ( ) . Specifically , for each
* * table in the changeset , there exists a database table with :
* *
* * < ul >
* * < li > The name identified by the changeset , and
* * < li > at least as many columns as recorded in the changeset , and
* * < li > the primary key columns in the same position as recorded in
* * the changeset .
* * < / ul >
* *
* * The output of the changegroup object always has the same schema as the
* * database nominated using this function . In cases where changesets passed
* * to sqlite3changegroup_add ( ) have fewer columns than the corresponding table
* * in the database schema , these are filled in using the default column
* * values from the database schema . This makes it possible to combined
* * changesets that have different numbers of columns for a single table
* * within a changegroup , provided that they are otherwise compatible .
*/
int sqlite3changegroup_schema ( sqlite3_changegroup * , sqlite3 * , const char * zDb ) ;
2015-06-11 17:26:10 +00:00
/*
2016-08-27 18:35:55 +00:00
* * CAPI3REF : Add A Changeset To A Changegroup
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changegroup
2016-08-27 18:35:55 +00:00
* *
2015-06-11 17:26:10 +00:00
* * Add all changes within the changeset ( or patchset ) in buffer pData ( size
* * nData bytes ) to the changegroup .
* *
* * If the buffer contains a patchset , then all prior calls to this function
* * on the same changegroup object must also have specified patchsets . Or , if
* * the buffer contains a changeset , so must have the earlier calls to this
* * function . Otherwise , SQLITE_ERROR is returned and no changes are added
* * to the changegroup .
* *
* * Rows within the changeset and changegroup are identified by the values in
* * their PRIMARY KEY columns . A change in the changeset is considered to
* * apply to the same row as a change already present in the changegroup if
* * the two rows have the same primary key .
* *
2016-09-28 16:05:53 +00:00
* * Changes to rows that do not already appear in the changegroup are
2015-06-11 17:26:10 +00:00
* * simply copied into it . Or , if both the new changeset and the changegroup
* * contain changes that apply to a single row , the final contents of the
* * changegroup depends on the type of each change , as follows :
2011-04-15 12:04:50 +00:00
* *
* * < table border = 1 style = " margin-left:8ex;margin-right:8ex " >
2015-06-11 17:26:10 +00:00
* * < tr > < th style = " white-space:pre " > Existing Change < / th >
* * < th style = " white-space:pre " > New Change < / th >
2011-04-15 12:04:50 +00:00
* * < th > Output Change
* * < tr > < td > INSERT < td > INSERT < td >
2015-06-11 17:26:10 +00:00
* * The new change is ignored . This case does not occur if the new
* * changeset was recorded immediately after the changesets already
* * added to the changegroup .
2011-04-15 12:04:50 +00:00
* * < tr > < td > INSERT < td > UPDATE < td >
2015-06-11 17:26:10 +00:00
* * The INSERT change remains in the changegroup . The values in the
* * INSERT change are modified as if the row was inserted by the
* * existing change and then updated according to the new change .
2011-04-15 12:04:50 +00:00
* * < tr > < td > INSERT < td > DELETE < td >
2015-06-11 17:26:10 +00:00
* * The existing INSERT is removed from the changegroup . The DELETE is
* * not added .
2011-04-15 12:04:50 +00:00
* * < tr > < td > UPDATE < td > INSERT < td >
2015-06-11 17:26:10 +00:00
* * The new change is ignored . This case does not occur if the new
* * changeset was recorded immediately after the changesets already
* * added to the changegroup .
2011-04-15 12:04:50 +00:00
* * < tr > < td > UPDATE < td > UPDATE < td >
2015-06-11 17:26:10 +00:00
* * The existing UPDATE remains within the changegroup . It is amended
* * so that the accompanying values are as if the row was updated once
* * by the existing change and then again by the new change .
2011-04-15 12:04:50 +00:00
* * < tr > < td > UPDATE < td > DELETE < td >
2015-06-11 17:26:10 +00:00
* * The existing UPDATE is replaced by the new DELETE within the
* * changegroup .
2011-04-15 12:04:50 +00:00
* * < tr > < td > DELETE < td > INSERT < td >
2015-06-11 17:26:10 +00:00
* * If one or more of the column values in the row inserted by the
* * new change differ from those in the row deleted by the existing
* * change , the existing DELETE is replaced by an UPDATE within the
* * changegroup . Otherwise , if the inserted row is exactly the same
* * as the deleted row , the existing DELETE is simply discarded .
2011-04-15 12:04:50 +00:00
* * < tr > < td > DELETE < td > UPDATE < td >
2015-06-11 17:26:10 +00:00
* * The new change is ignored . This case does not occur if the new
* * changeset was recorded immediately after the changesets already
* * added to the changegroup .
2011-04-15 12:04:50 +00:00
* * < tr > < td > DELETE < td > DELETE < td >
2015-06-11 17:26:10 +00:00
* * The new change is ignored . This case does not occur if the new
* * changeset was recorded immediately after the changesets already
* * added to the changegroup .
2011-04-15 12:04:50 +00:00
* * < / table >
* *
2015-06-11 17:26:10 +00:00
* * If the new changeset contains changes to a table that is already present
* * in the changegroup , then the number of columns and the position of the
* * primary key columns for the table must be consistent . If this is not the
2023-10-04 21:15:24 +00:00
* * case , this function fails with SQLITE_SCHEMA . Except , if the changegroup
* * object has been configured with a database schema using the
* * sqlite3changegroup_schema ( ) API , then it is possible to combine changesets
* * with different numbers of columns for a single table , provided that
* * they are otherwise compatible .
* *
* * If the input changeset appears to be corrupt and the corruption is
* * detected , SQLITE_CORRUPT is returned . Or , if an out - of - memory condition
* * occurs during processing , this function returns SQLITE_NOMEM .
* *
* * In all cases , if an error occurs the state of the final contents of the
* * changegroup is undefined . If no error occurs , SQLITE_OK is returned .
2011-04-14 18:01:41 +00:00
*/
2015-06-11 17:26:10 +00:00
int sqlite3changegroup_add ( sqlite3_changegroup * , int nData , void * pData ) ;
/*
2016-08-27 18:35:55 +00:00
* * CAPI3REF : Obtain A Composite Changeset From A Changegroup
2018-02-28 22:21:29 +00:00
* * METHOD : sqlite3_changegroup
2016-08-27 18:35:55 +00:00
* *
2015-06-11 17:26:10 +00:00
* * Obtain a buffer containing a changeset ( or patchset ) representing the
* * current contents of the changegroup . If the inputs to the changegroup
* * were themselves changesets , the output is a changeset . Or , if the
* * inputs were patchsets , the output is also a patchset .
* *
2015-10-01 16:35:57 +00:00
* * As with the output of the sqlite3session_changeset ( ) and
* * sqlite3session_patchset ( ) functions , all changes related to a single
* * table are grouped together in the output of this function . Tables appear
* * in the same order as for the very first changeset added to the changegroup .
* * If the second or subsequent changesets added to the changegroup contain
* * changes for tables that do not appear in the first changeset , they are
* * appended onto the end of the output changeset , again in the order in
* * which they are first encountered .
* *
2015-06-11 17:26:10 +00:00
* * If an error occurs , an SQLite error code is returned and the output
* * variables ( * pnData ) and ( * ppData ) are set to 0. Otherwise , SQLITE_OK
* * is returned and the output variables are set to the size of and a
* * pointer to the output buffer , respectively . In this case it is the
* * responsibility of the caller to eventually free the buffer using a
* * call to sqlite3_free ( ) .
*/
int sqlite3changegroup_output (
sqlite3_changegroup * ,
int * pnData , /* OUT: Size of output buffer in bytes */
void * * ppData /* OUT: Pointer to output buffer */
2011-04-14 11:16:21 +00:00
) ;
2015-06-11 17:26:10 +00:00
/*
2016-08-27 18:35:55 +00:00
* * CAPI3REF : Delete A Changegroup Object
2018-02-28 22:21:29 +00:00
* * DESTRUCTOR : sqlite3_changegroup
2015-06-11 17:26:10 +00:00
*/
void sqlite3changegroup_delete ( sqlite3_changegroup * ) ;
2011-03-11 19:05:52 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Apply A Changeset To A Database
* *
2018-03-21 19:46:36 +00:00
* * Apply a changeset or patchset to a database . These functions attempt to
* * update the " main " database attached to handle db with the changes found in
* * the changeset passed via the second and third arguments .
2011-03-18 16:13:53 +00:00
* *
2018-03-21 19:46:36 +00:00
* * The fourth argument ( xFilter ) passed to these functions is the " filter
2011-07-13 15:21:02 +00:00
* * callback " . If it is not NULL, then for each table affected by at least one
* * change in the changeset , the filter callback is invoked with
* * the table name as the second argument , and a copy of the context pointer
2018-03-21 19:46:36 +00:00
* * passed as the sixth argument as the first . If the " filter callback "
* * returns zero , then no attempt is made to apply any changes to the table .
* * Otherwise , if the return value is non - zero or the xFilter argument to
* * is NULL , all changes related to the table are attempted .
2011-07-13 15:21:02 +00:00
* *
* * For each table that is not excluded by the filter callback , this function
* * tests that the target database contains a compatible table . A table is
* * considered compatible if all of the following are true :
2011-03-18 16:13:53 +00:00
* *
* * < ul >
* * < li > The table has the same name as the name recorded in the
* * changeset , and
2017-02-04 17:33:30 +00:00
* * < li > The table has at least as many columns as recorded in the
2011-03-18 16:13:53 +00:00
* * changeset , and
* * < li > The table has primary key columns in the same position as
* * recorded in the changeset .
* * < / ul >
* *
2011-07-13 15:21:02 +00:00
* * If there is no compatible table , it is not an error , but none of the
* * changes associated with the table are applied . A warning message is issued
* * via the sqlite3_log ( ) mechanism with the error code SQLITE_SCHEMA . At most
* * one such warning is issued for each table in the changeset .
2011-03-18 16:13:53 +00:00
* *
2011-07-13 15:21:02 +00:00
* * For each change for which there is a compatible table , an attempt is made
* * to modify the table contents according to the UPDATE , INSERT or DELETE
* * change . If a change cannot be applied cleanly , the conflict handler
* * function passed as the fifth argument to sqlite3changeset_apply ( ) may be
* * invoked . A description of exactly when the conflict handler is invoked for
* * each type of change is below .
2011-03-18 16:13:53 +00:00
* *
2014-08-18 16:03:46 +00:00
* * Unlike the xFilter argument , xConflict may not be passed NULL . The results
* * of passing anything other than a valid function pointer as the xConflict
* * argument are undefined .
* *
2011-03-18 16:13:53 +00:00
* * Each time the conflict handler function is invoked , it must return one
* * of [ SQLITE_CHANGESET_OMIT ] , [ SQLITE_CHANGESET_ABORT ] or
* * [ SQLITE_CHANGESET_REPLACE ] . SQLITE_CHANGESET_REPLACE may only be returned
* * if the second argument passed to the conflict handler is either
* * SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT . If the conflict - handler
* * returns an illegal value , any changes already made are rolled back and
* * the call to sqlite3changeset_apply ( ) returns SQLITE_MISUSE . Different
* * actions are taken by sqlite3changeset_apply ( ) depending on the value
* * returned by each invocation of the conflict - handler function . Refer to
* * the documentation for the three
* * [ SQLITE_CHANGESET_OMIT | available return values ] for details .
* *
* * < dl >
* * < dt > DELETE Changes < dd >
2018-03-21 19:46:36 +00:00
* * For each DELETE change , the function checks if the target database
2011-03-18 16:13:53 +00:00
* * contains a row with the same primary key value ( or values ) as the
* * original row values stored in the changeset . If it does , and the values
* * stored in all non - primary key columns also match the values stored in
* * the changeset the row is deleted from the target database .
* *
* * If a row with matching primary key values is found , but one or more of
* * the non - primary key fields contains a value different from the original
* * row value stored in the changeset , the conflict - handler function is
2017-02-04 17:33:30 +00:00
* * invoked with [ SQLITE_CHANGESET_DATA ] as the second argument . If the
* * database table has more columns than are recorded in the changeset ,
* * only the values of those non - primary key fields are compared against
* * the current database contents - any trailing database table columns
* * are ignored .
2011-03-18 16:13:53 +00:00
* *
* * If no row with matching primary key values is found in the database ,
* * the conflict - handler function is invoked with [ SQLITE_CHANGESET_NOTFOUND ]
* * passed as the second argument .
* *
* * If the DELETE operation is attempted , but SQLite returns SQLITE_CONSTRAINT
* * ( which can only happen if a foreign key constraint is violated ) , the
* * conflict - handler function is invoked with [ SQLITE_CHANGESET_CONSTRAINT ]
* * passed as the second argument . This includes the case where the DELETE
* * operation is attempted because an earlier call to the conflict handler
* * function returned [ SQLITE_CHANGESET_REPLACE ] .
* *
* * < dt > INSERT Changes < dd >
* * For each INSERT change , an attempt is made to insert the new row into
2017-02-04 17:33:30 +00:00
* * the database . If the changeset row contains fewer fields than the
* * database table , the trailing fields are populated with their default
* * values .
2011-03-18 16:13:53 +00:00
* *
* * If the attempt to insert the row fails because the database already
* * contains a row with the same primary key values , the conflict handler
* * function is invoked with the second argument set to
* * [ SQLITE_CHANGESET_CONFLICT ] .
* *
* * If the attempt to insert the row fails because of some other constraint
* * violation ( e . g . NOT NULL or UNIQUE ) , the conflict handler function is
* * invoked with the second argument set to [ SQLITE_CHANGESET_CONSTRAINT ] .
* * This includes the case where the INSERT operation is re - attempted because
* * an earlier call to the conflict handler function returned
* * [ SQLITE_CHANGESET_REPLACE ] .
* *
* * < dt > UPDATE Changes < dd >
2018-03-21 19:46:36 +00:00
* * For each UPDATE change , the function checks if the target database
2011-03-18 16:13:53 +00:00
* * contains a row with the same primary key value ( or values ) as the
* * original row values stored in the changeset . If it does , and the values
2017-02-04 17:33:30 +00:00
* * stored in all modified non - primary key columns also match the values
* * stored in the changeset the row is updated within the target database .
2011-03-18 16:13:53 +00:00
* *
* * If a row with matching primary key values is found , but one or more of
2017-02-04 17:33:30 +00:00
* * the modified non - primary key fields contains a value different from an
* * original row value stored in the changeset , the conflict - handler function
* * is invoked with [ SQLITE_CHANGESET_DATA ] as the second argument . Since
2011-03-18 16:13:53 +00:00
* * UPDATE changes only contain values for non - primary key fields that are
* * to be modified , only those fields need to match the original values to
* * avoid the SQLITE_CHANGESET_DATA conflict - handler callback .
* *
* * If no row with matching primary key values is found in the database ,
* * the conflict - handler function is invoked with [ SQLITE_CHANGESET_NOTFOUND ]
* * passed as the second argument .
* *
* * If the UPDATE operation is attempted , but SQLite returns
* * SQLITE_CONSTRAINT , the conflict - handler function is invoked with
* * [ SQLITE_CHANGESET_CONSTRAINT ] passed as the second argument .
* * This includes the case where the UPDATE operation is attempted after
* * an earlier call to the conflict handler function returned
* * [ SQLITE_CHANGESET_REPLACE ] .
* * < / dl >
2011-03-11 19:05:52 +00:00
* *
* * It is safe to execute SQL statements , including those that write to the
* * table that the callback related to , from within the xConflict callback .
2019-11-26 14:24:12 +00:00
* * This can be used to further customize the application ' s conflict
2011-03-11 19:05:52 +00:00
* * resolution strategy .
2011-03-18 16:13:53 +00:00
* *
2018-03-21 19:46:36 +00:00
* * All changes made by these functions are enclosed in a savepoint transaction .
2011-03-18 16:13:53 +00:00
* * If any other error ( aside from a constraint failure when attempting to
* * write to the target database ) occurs , then the savepoint transaction is
* * rolled back , restoring the target database to its original state , and an
* * SQLite error code returned .
2018-03-21 19:46:36 +00:00
* *
* * If the output parameters ( ppRebase ) and ( pnRebase ) are non - NULL and
* * the input is a changeset ( not a patchset ) , then sqlite3changeset_apply_v2 ( )
* * may set ( * ppRebase ) to point to a " rebase " that may be used with the
* * sqlite3_rebaser APIs buffer before returning . In this case ( * pnRebase )
* * is set to the size of the buffer in bytes . It is the responsibility of the
* * caller to eventually free any such buffer using sqlite3_free ( ) . The buffer
* * is only allocated and populated if one or more conflicts were encountered
* * while applying the patchset . See comments surrounding the sqlite3_rebaser
* * APIs for further details .
2018-04-09 11:43:58 +00:00
* *
* * The behavior of sqlite3changeset_apply_v2 ( ) and its streaming equivalent
* * may be modified by passing a combination of
* * [ SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags ] as the 9 th parameter .
* *
* * Note that the sqlite3changeset_apply_v2 ( ) API is still < b > experimental < / b >
* * and therefore subject to change .
2011-03-11 19:05:52 +00:00
*/
int sqlite3changeset_apply (
2011-03-15 16:37:27 +00:00
sqlite3 * db , /* Apply change to "main" db of this handle */
int nChangeset , /* Size of changeset in bytes */
void * pChangeset , /* Changeset blob */
2011-07-13 15:21:02 +00:00
int ( * xFilter ) (
void * pCtx , /* Copy of sixth arg to _apply() */
const char * zTab /* Table name */
) ,
2011-03-11 19:05:52 +00:00
int ( * xConflict ) (
2011-07-13 15:21:02 +00:00
void * pCtx , /* Copy of sixth arg to _apply() */
2011-03-11 19:05:52 +00:00
int eConflict , /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter * p /* Handle describing change and conflict */
) ,
2011-03-15 16:37:27 +00:00
void * pCtx /* First argument passed to xConflict */
2011-03-11 19:05:52 +00:00
) ;
2018-03-13 20:31:23 +00:00
int sqlite3changeset_apply_v2 (
sqlite3 * db , /* Apply change to "main" db of this handle */
int nChangeset , /* Size of changeset in bytes */
void * pChangeset , /* Changeset blob */
int ( * xFilter ) (
void * pCtx , /* Copy of sixth arg to _apply() */
const char * zTab /* Table name */
) ,
int ( * xConflict ) (
void * pCtx , /* Copy of sixth arg to _apply() */
int eConflict , /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter * p /* Handle describing change and conflict */
) ,
void * pCtx , /* First argument passed to xConflict */
2018-04-09 11:43:58 +00:00
void * * ppRebase , int * pnRebase , /* OUT: Rebase data */
2018-10-20 13:48:09 +00:00
int flags /* SESSION_CHANGESETAPPLY_* flags */
2018-03-13 20:31:23 +00:00
) ;
2018-04-09 11:43:58 +00:00
/*
* * CAPI3REF : Flags for sqlite3changeset_apply_v2
* *
* * The following flags may passed via the 9 th parameter to
* * [ sqlite3changeset_apply_v2 ] and [ sqlite3changeset_apply_v2_strm ] :
* *
* * < dl >
* * < dt > SQLITE_CHANGESETAPPLY_NOSAVEPOINT < dd >
* * Usually , the sessions module encloses all operations performed by
* * a single call to apply_v2 ( ) or apply_v2_strm ( ) in a [ SAVEPOINT ] . The
* * SAVEPOINT is committed if the changeset or patchset is successfully
* * applied , or rolled back if an error occurs . Specifying this flag
* * causes the sessions module to omit this savepoint . In this case , if the
* * caller has an open transaction or savepoint when apply_v2 ( ) is called ,
* * it may revert the partially applied changeset by rolling it back .
2018-10-18 14:59:21 +00:00
* *
* * < dt > SQLITE_CHANGESETAPPLY_INVERT < dd >
* * Invert the changeset before applying it . This is equivalent to inverting
* * a changeset using sqlite3changeset_invert ( ) before applying it . It is
* * an error to specify this flag with a patchset .
2023-03-08 18:03:04 +00:00
* *
* * < dt > SQLITE_CHANGESETAPPLY_IGNORENOOP < dd >
* * Do not invoke the conflict handler callback for any changes that
* * would not actually modify the database even if they were applied .
* * Specifically , this means that the conflict handler is not invoked
* * for :
* * < ul >
* * < li > a delete change if the row being deleted cannot be found ,
* * < li > an update change if the modified fields are already set to
* * their new values in the conflicting row , or
* * < li > an insert change if all fields of the conflicting row match
* * the row being inserted .
* * < / ul >
2023-10-20 17:06:39 +00:00
* *
* * < dt > SQLITE_CHANGESETAPPLY_FKNOACTION < dd >
* * If this flag it set , then all foreign key constraints in the target
* * database behave as if they were declared with " ON UPDATE NO ACTION ON
* * DELETE NO ACTION " , even if they are actually CASCADE, RESTRICT, SET NULL
* * or SET DEFAULT .
2018-04-09 11:43:58 +00:00
*/
# define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
2018-10-18 14:59:21 +00:00
# define SQLITE_CHANGESETAPPLY_INVERT 0x0002
2023-03-08 18:03:04 +00:00
# define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
2023-10-20 17:06:39 +00:00
# define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
2018-04-09 11:43:58 +00:00
2011-03-14 19:49:23 +00:00
/*
2011-03-22 02:03:23 +00:00
* * CAPI3REF : Constants Passed To The Conflict Handler
2011-03-20 11:20:41 +00:00
* *
2011-03-18 16:13:53 +00:00
* * Values that may be passed as the second argument to a conflict - handler .
2011-03-14 19:49:23 +00:00
* *
2011-03-18 16:13:53 +00:00
* * < dl >
* * < dt > SQLITE_CHANGESET_DATA < dd >
2011-03-14 19:49:23 +00:00
* * The conflict handler is invoked with CHANGESET_DATA as the second argument
* * when processing a DELETE or UPDATE change if a row with the required
* * PRIMARY KEY fields is present in the database , but one or more other
* * ( non primary - key ) fields modified by the update do not contain the
* * expected " before " values .
* *
* * The conflicting row , in this case , is the database row with the matching
* * primary key .
* *
2011-03-18 16:13:53 +00:00
* * < dt > SQLITE_CHANGESET_NOTFOUND < dd >
2011-03-14 19:49:23 +00:00
* * The conflict handler is invoked with CHANGESET_NOTFOUND as the second
* * argument when processing a DELETE or UPDATE change if a row with the
* * required PRIMARY KEY fields is not present in the database .
* *
* * There is no conflicting row in this case . The results of invoking the
* * sqlite3changeset_conflict ( ) API are undefined .
* *
2011-03-18 16:13:53 +00:00
* * < dt > SQLITE_CHANGESET_CONFLICT < dd >
2011-03-14 19:49:23 +00:00
* * CHANGESET_CONFLICT is passed as the second argument to the conflict
2011-03-18 16:13:53 +00:00
* * handler while processing an INSERT change if the operation would result
* * in duplicate primary key values .
2011-03-14 19:49:23 +00:00
* *
* * The conflicting row in this case is the database row with the matching
* * primary key .
2013-07-03 19:53:05 +00:00
* *
* * < dt > SQLITE_CHANGESET_FOREIGN_KEY < dd >
* * If foreign key handling is enabled , and applying a changeset leaves the
* * database in a state containing foreign key violations , the conflict
* * handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
* * exactly once before the changeset is committed . If the conflict handler
* * returns CHANGESET_OMIT , the changes , including those that caused the
* * foreign key constraint violation , are committed . Or , if it returns
* * CHANGESET_ABORT , the changeset is rolled back .
* *
* * No current or conflicting row information is provided . The only function
* * it is possible to call on the supplied sqlite3_changeset_iter handle
* * is sqlite3changeset_fk_conflicts ( ) .
2011-03-14 19:49:23 +00:00
* *
2011-03-18 16:13:53 +00:00
* * < dt > SQLITE_CHANGESET_CONSTRAINT < dd >
2011-03-14 19:49:23 +00:00
* * If any other constraint violation occurs while applying a change ( i . e .
2013-07-03 19:53:05 +00:00
* * a UNIQUE , CHECK or NOT NULL constraint ) , the conflict handler is
* * invoked with CHANGESET_CONSTRAINT as the second argument .
2011-03-14 19:49:23 +00:00
* *
* * There is no conflicting row in this case . The results of invoking the
* * sqlite3changeset_conflict ( ) API are undefined .
2013-07-03 19:53:05 +00:00
* *
2011-03-18 16:13:53 +00:00
* * < / dl >
2011-03-14 19:49:23 +00:00
*/
2013-07-03 19:53:05 +00:00
# define SQLITE_CHANGESET_DATA 1
# define SQLITE_CHANGESET_NOTFOUND 2
# define SQLITE_CHANGESET_CONFLICT 3
# define SQLITE_CHANGESET_CONSTRAINT 4
# define SQLITE_CHANGESET_FOREIGN_KEY 5
2011-03-11 19:05:52 +00:00
2011-03-14 19:49:23 +00:00
/*
2011-03-20 11:20:41 +00:00
* * CAPI3REF : Constants Returned By The Conflict Handler
* *
* * A conflict handler callback must return one of the following three values .
2011-03-14 19:49:23 +00:00
* *
2011-03-18 16:13:53 +00:00
* * < dl >
* * < dt > SQLITE_CHANGESET_OMIT < dd >
2011-03-14 19:49:23 +00:00
* * If a conflict handler returns this value no special action is taken . The
2011-03-18 16:13:53 +00:00
* * change that caused the conflict is not applied . The session module
* * continues to the next change in the changeset .
2011-03-14 19:49:23 +00:00
* *
2011-03-18 16:13:53 +00:00
* * < dt > SQLITE_CHANGESET_REPLACE < dd >
2011-03-14 19:49:23 +00:00
* * This value may only be returned if the second argument to the conflict
* * handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT . If this
* * is not the case , any changes applied so far are rolled back and the
* * call to sqlite3changeset_apply ( ) returns SQLITE_MISUSE .
* *
* * If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
* * handler , then the conflicting row is either updated or deleted , depending
* * on the type of change .
* *
* * If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
* * handler , then the conflicting row is removed from the database and a
* * second attempt to apply the change is made . If this second attempt fails ,
* * the original row is restored to the database before continuing .
* *
2011-03-18 16:13:53 +00:00
* * < dt > SQLITE_CHANGESET_ABORT < dd >
2011-03-14 19:49:23 +00:00
* * If this value is returned , any changes applied so far are rolled back
2011-03-18 16:13:53 +00:00
* * and the call to sqlite3changeset_apply ( ) returns SQLITE_ABORT .
* * < / dl >
2011-03-14 19:49:23 +00:00
*/
2011-03-11 19:05:52 +00:00
# define SQLITE_CHANGESET_OMIT 0
# define SQLITE_CHANGESET_REPLACE 1
# define SQLITE_CHANGESET_ABORT 2
2011-03-09 11:17:05 +00:00
2018-03-16 18:02:47 +00:00
/*
* * CAPI3REF : Rebasing changesets
2018-03-23 17:36:31 +00:00
* * EXPERIMENTAL
2018-03-16 18:02:47 +00:00
* *
2018-03-20 20:27:03 +00:00
* * Suppose there is a site hosting a database in state S0 . And that
* * modifications are made that move that database to state S1 and a
* * changeset recorded ( the " local " changeset ) . Then , a changeset based
* * on S0 is received from another site ( the " remote " changeset ) and
* * applied to the database . The database is then in state
* * ( S1 + " remote " ) , where the exact state depends on any conflict
* * resolution decisions ( OMIT or REPLACE ) made while applying " remote " .
* * Rebasing a changeset is to update it to take those conflict
* * resolution decisions into account , so that the same conflicts
* * do not have to be resolved elsewhere in the network .
* *
* * For example , if both the local and remote changesets contain an
* * INSERT of the same key on " CREATE TABLE t1(a PRIMARY KEY, b) " :
* *
* * local : INSERT INTO t1 VALUES ( 1 , ' v1 ' ) ;
* * remote : INSERT INTO t1 VALUES ( 1 , ' v2 ' ) ;
* *
* * and the conflict resolution is REPLACE , then the INSERT change is
* * removed from the local changeset ( it was overridden ) . Or , if the
* * conflict resolution was " OMIT " , then the local changeset is modified
* * to instead contain :
* *
* * UPDATE t1 SET b = ' v2 ' WHERE a = 1 ;
* *
* * Changes within the local changeset are rebased as follows :
2018-03-16 18:02:47 +00:00
* *
* * < dl >
2018-03-20 20:27:03 +00:00
* * < dt > Local INSERT < dd >
2018-03-16 18:02:47 +00:00
* * This may only conflict with a remote INSERT . If the conflict
* * resolution was OMIT , then add an UPDATE change to the rebased
* * changeset . Or , if the conflict resolution was REPLACE , add
* * nothing to the rebased changeset .
* *
2018-03-20 20:27:03 +00:00
* * < dt > Local DELETE < dd >
2018-03-16 18:02:47 +00:00
* * This may conflict with a remote UPDATE or DELETE . In both cases the
* * only possible resolution is OMIT . If the remote operation was a
* * DELETE , then add no change to the rebased changeset . If the remote
2018-03-21 17:29:53 +00:00
* * operation was an UPDATE , then the old . * fields of change are updated
2018-03-20 20:27:03 +00:00
* * to reflect the new . * values in the UPDATE .
2018-03-16 18:02:47 +00:00
* *
2018-03-20 20:27:03 +00:00
* * < dt > Local UPDATE < dd >
2018-03-16 18:02:47 +00:00
* * This may conflict with a remote UPDATE or DELETE . If it conflicts
* * with a DELETE , and the conflict resolution was OMIT , then the update
* * is changed into an INSERT . Any undefined values in the new . * record
2018-03-21 17:29:53 +00:00
* * from the update change are filled in using the old . * values from
2018-03-16 18:02:47 +00:00
* * the conflicting DELETE . Or , if the conflict resolution was REPLACE ,
* * the UPDATE change is simply omitted from the rebased changeset .
* *
* * If conflict is with a remote UPDATE and the resolution is OMIT , then
* * the old . * values are rebased using the new . * values in the remote
* * change . Or , if the resolution is REPLACE , then the change is copied
* * into the rebased changeset with updates to columns also updated by
2018-03-21 17:29:53 +00:00
* * the conflicting remote UPDATE removed . If this means no columns would
* * be updated , the change is omitted .
2018-03-16 18:02:47 +00:00
* * < / dl >
2018-03-20 20:27:03 +00:00
* *
* * A local change may be rebased against multiple remote changes
2018-03-21 17:29:53 +00:00
* * simultaneously . If a single key is modified by multiple remote
* * changesets , they are combined as follows before the local changeset
* * is rebased :
* *
* * < ul >
* * < li > If there has been one or more REPLACE resolutions on a
* * key , it is rebased according to a REPLACE .
* *
* * < li > If there have been no REPLACE resolutions on a key , then
* * the local changeset is rebased according to the most recent
* * of the OMIT resolutions .
* * < / ul >
* *
* * Note that conflict resolutions from multiple remote changesets are
* * combined on a per - field basis , not per - row . This means that in the
* * case of multiple remote UPDATE operations , some fields of a single
* * local change may be rebased for REPLACE while others are rebased for
* * OMIT .
2018-03-21 19:46:36 +00:00
* *
* * In order to rebase a local changeset , the remote changeset must first
* * be applied to the local database using sqlite3changeset_apply_v2 ( ) and
* * the buffer of rebase information captured . Then :
* *
* * < ol >
* * < li > An sqlite3_rebaser object is created by calling
* * sqlite3rebaser_create ( ) .
* * < li > The new object is configured with the rebase buffer obtained from
* * sqlite3changeset_apply_v2 ( ) by calling sqlite3rebaser_configure ( ) .
* * If the local changeset is to be rebased against multiple remote
* * changesets , then sqlite3rebaser_configure ( ) should be called
* * multiple times , in the same order that the multiple
* * sqlite3changeset_apply_v2 ( ) calls were made .
* * < li > Each local changeset is rebased by calling sqlite3rebaser_rebase ( ) .
* * < li > The sqlite3_rebaser object is deleted by calling
* * sqlite3rebaser_delete ( ) .
* * < / ol >
2018-03-16 18:02:47 +00:00
*/
2018-03-14 21:06:58 +00:00
typedef struct sqlite3_rebaser sqlite3_rebaser ;
2018-03-21 19:46:36 +00:00
/*
2018-03-23 17:36:31 +00:00
* * CAPI3REF : Create a changeset rebaser object .
* * EXPERIMENTAL
2018-03-21 19:46:36 +00:00
* *
* * Allocate a new changeset rebaser object . If successful , set ( * ppNew ) to
* * point to the new object and return SQLITE_OK . Otherwise , if an error
* * occurs , return an SQLite error code ( e . g . SQLITE_NOMEM ) and set ( * ppNew )
* * to NULL .
*/
2018-03-14 21:06:58 +00:00
int sqlite3rebaser_create ( sqlite3_rebaser * * ppNew ) ;
2018-03-21 19:46:36 +00:00
/*
2018-03-23 17:36:31 +00:00
* * CAPI3REF : Configure a changeset rebaser object .
* * EXPERIMENTAL
2018-03-21 19:46:36 +00:00
* *
* * Configure the changeset rebaser object to rebase changesets according
* * to the conflict resolutions described by buffer pRebase ( size nRebase
* * bytes ) , which must have been obtained from a previous call to
* * sqlite3changeset_apply_v2 ( ) .
*/
2018-03-14 21:06:58 +00:00
int sqlite3rebaser_configure (
sqlite3_rebaser * ,
int nRebase , const void * pRebase
) ;
2018-03-21 19:46:36 +00:00
/*
2018-03-23 17:36:31 +00:00
* * CAPI3REF : Rebase a changeset
* * EXPERIMENTAL
2018-03-21 19:46:36 +00:00
* *
* * Argument pIn must point to a buffer containing a changeset nIn bytes
* * in size . This function allocates and populates a buffer with a copy
2019-11-26 14:24:12 +00:00
* * of the changeset rebased according to the configuration of the
2018-03-21 19:46:36 +00:00
* * rebaser object passed as the first argument . If successful , ( * ppOut )
2019-03-29 11:48:10 +00:00
* * is set to point to the new buffer containing the rebased changeset and
2018-03-21 19:46:36 +00:00
* * ( * pnOut ) to its size in bytes and SQLITE_OK returned . It is the
* * responsibility of the caller to eventually free the new buffer using
* * sqlite3_free ( ) . Otherwise , if an error occurs , ( * ppOut ) and ( * pnOut )
* * are set to zero and an SQLite error code returned .
*/
2018-03-14 21:06:58 +00:00
int sqlite3rebaser_rebase (
sqlite3_rebaser * ,
int nIn , const void * pIn ,
int * pnOut , void * * ppOut
) ;
2018-03-21 19:46:36 +00:00
/*
2018-03-23 17:36:31 +00:00
* * CAPI3REF : Delete a changeset rebaser object .
* * EXPERIMENTAL
2018-03-21 19:46:36 +00:00
* *
* * Delete the changeset rebaser object and all associated resources . There
* * should be one call to this function for each successful invocation
* * of sqlite3rebaser_create ( ) .
*/
2018-03-15 19:25:40 +00:00
void sqlite3rebaser_delete ( sqlite3_rebaser * p ) ;
2018-03-14 21:06:58 +00:00
2014-09-27 12:26:18 +00:00
/*
* * CAPI3REF : Streaming Versions of API functions .
* *
2014-09-27 20:45:48 +00:00
* * The six streaming API xxx_strm ( ) functions serve similar purposes to the
2014-09-27 12:26:18 +00:00
* * corresponding non - streaming API functions :
* *
* * < table border = 1 style = " margin-left:8ex;margin-right:8ex " >
* * < tr > < th > Streaming function < th > Non - streaming equivalent < / th >
2017-10-04 16:35:01 +00:00
* * < tr > < td > sqlite3changeset_apply_strm < td > [ sqlite3changeset_apply ]
2018-04-09 11:43:58 +00:00
* * < tr > < td > sqlite3changeset_apply_strm_v2 < td > [ sqlite3changeset_apply_v2 ]
2017-10-04 16:35:01 +00:00
* * < tr > < td > sqlite3changeset_concat_strm < td > [ sqlite3changeset_concat ]
* * < tr > < td > sqlite3changeset_invert_strm < td > [ sqlite3changeset_invert ]
* * < tr > < td > sqlite3changeset_start_strm < td > [ sqlite3changeset_start ]
* * < tr > < td > sqlite3session_changeset_strm < td > [ sqlite3session_changeset ]
* * < tr > < td > sqlite3session_patchset_strm < td > [ sqlite3session_patchset ]
2014-09-27 12:26:18 +00:00
* * < / table >
* *
* * Non - streaming functions that accept changesets ( or patchsets ) as input
* * require that the entire changeset be stored in a single buffer in memory .
* * Similarly , those that return a changeset or patchset do so by returning
* * a pointer to a single large buffer allocated using sqlite3_malloc ( ) .
* * Normally this is convenient . However , if an application running in a
* * low - memory environment is required to handle very large changesets , the
* * large contiguous memory allocations required can become onerous .
* *
* * In order to avoid this problem , instead of a single large buffer , input
* * is passed to a streaming API functions by way of a callback function that
* * the sessions module invokes to incrementally request input data as it is
* * required . In all cases , a pair of API function parameters such as
* *
* * < pre >
* * & nbsp ; int nChangeset ,
* * & nbsp ; void * pChangeset ,
* * < / pre >
* *
* * Is replaced by :
* *
* * < pre >
* * & nbsp ; int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
* * & nbsp ; void * pIn ,
* * < / pre >
* *
* * Each time the xInput callback is invoked by the sessions module , the first
* * argument passed is a copy of the supplied pIn context pointer . The second
* * argument , pData , points to a buffer ( * pnData ) bytes in size . Assuming no
* * error occurs the xInput method should copy up to ( * pnData ) bytes of data
* * into the buffer and set ( * pnData ) to the actual number of bytes copied
* * before returning SQLITE_OK . If the input is completely exhausted , ( * pnData )
* * should be set to zero to indicate this . Or , if an error occurs , an SQLite
* * error code should be returned . In all cases , if an xInput callback returns
* * an error , all processing is abandoned and the streaming API function
* * returns a copy of the error code to the caller .
* *
2014-09-27 20:45:48 +00:00
* * In the case of sqlite3changeset_start_strm ( ) , the xInput callback may be
2014-09-27 12:26:18 +00:00
* * invoked by the sessions module at any point during the lifetime of the
* * iterator . If such an xInput callback returns an error , the iterator enters
* * an error state , whereby all subsequent calls to iterator functions
* * immediately fail with the same error code as returned by xInput .
* *
* * Similarly , streaming API functions that return changesets ( or patchsets )
* * return them in chunks by way of a callback function instead of via a
* * pointer to a single large buffer . In this case , a pair of parameters such
* * as :
* *
* * < pre >
* * & nbsp ; int * pnChangeset ,
* * & nbsp ; void * * ppChangeset ,
* * < / pre >
* *
* * Is replaced by :
* *
* * < pre >
* * & nbsp ; int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
* * & nbsp ; void * pOut
* * < / pre >
* *
* * The xOutput callback is invoked zero or more times to return data to
* * the application . The first parameter passed to each call is a copy of the
* * pOut pointer supplied by the application . The second parameter , pData ,
* * points to a buffer nData bytes in size containing the chunk of output
* * data being returned . If the xOutput callback successfully processes the
* * supplied data , it should return SQLITE_OK to indicate success . Otherwise ,
* * it should return some other SQLite error code . In this case processing
* * is immediately abandoned and the streaming API function returns a copy
* * of the xOutput error code to the application .
* *
* * The sessions module never invokes an xOutput callback with the third
* * parameter set to a value less than or equal to zero . Other than this ,
* * no guarantees are made as to the size of the chunks of data returned .
*/
2014-09-27 20:45:48 +00:00
int sqlite3changeset_apply_strm (
2014-09-27 12:26:18 +00:00
sqlite3 * db , /* Apply change to "main" db of this handle */
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) , /* Input function */
void * pIn , /* First arg for xInput */
int ( * xFilter ) (
void * pCtx , /* Copy of sixth arg to _apply() */
const char * zTab /* Table name */
) ,
int ( * xConflict ) (
void * pCtx , /* Copy of sixth arg to _apply() */
int eConflict , /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter * p /* Handle describing change and conflict */
) ,
void * pCtx /* First argument passed to xConflict */
) ;
2018-03-13 20:31:23 +00:00
int sqlite3changeset_apply_v2_strm (
sqlite3 * db , /* Apply change to "main" db of this handle */
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) , /* Input function */
void * pIn , /* First arg for xInput */
int ( * xFilter ) (
void * pCtx , /* Copy of sixth arg to _apply() */
const char * zTab /* Table name */
) ,
int ( * xConflict ) (
void * pCtx , /* Copy of sixth arg to _apply() */
int eConflict , /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter * p /* Handle describing change and conflict */
) ,
void * pCtx , /* First argument passed to xConflict */
2018-04-09 11:43:58 +00:00
void * * ppRebase , int * pnRebase ,
int flags
2018-03-13 20:31:23 +00:00
) ;
2014-09-27 20:45:48 +00:00
int sqlite3changeset_concat_strm (
2014-09-27 12:26:18 +00:00
int ( * xInputA ) ( void * pIn , void * pData , int * pnData ) ,
void * pInA ,
int ( * xInputB ) ( void * pIn , void * pData , int * pnData ) ,
void * pInB ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2014-09-27 20:45:48 +00:00
int sqlite3changeset_invert_strm (
2014-09-27 12:26:18 +00:00
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
void * pIn ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2014-09-27 20:45:48 +00:00
int sqlite3changeset_start_strm (
2014-09-27 12:26:18 +00:00
sqlite3_changeset_iter * * pp ,
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
void * pIn
) ;
2018-10-20 13:48:09 +00:00
int sqlite3changeset_start_v2_strm (
sqlite3_changeset_iter * * pp ,
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
void * pIn ,
int flags
) ;
2014-09-27 20:45:48 +00:00
int sqlite3session_changeset_strm (
2014-09-27 12:26:18 +00:00
sqlite3_session * pSession ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2014-09-27 20:45:48 +00:00
int sqlite3session_patchset_strm (
2014-09-27 12:26:18 +00:00
sqlite3_session * pSession ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2015-06-11 17:26:10 +00:00
int sqlite3changegroup_add_strm ( sqlite3_changegroup * ,
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
void * pIn
) ;
int sqlite3changegroup_output_strm ( sqlite3_changegroup * ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2018-03-14 21:06:58 +00:00
int sqlite3rebaser_rebase_strm (
sqlite3_rebaser * pRebaser ,
int ( * xInput ) ( void * pIn , void * pData , int * pnData ) ,
void * pIn ,
int ( * xOutput ) ( void * pOut , const void * pData , int nData ) ,
void * pOut
) ;
2014-09-27 12:26:18 +00:00
2018-10-26 17:05:00 +00:00
/*
* * CAPI3REF : Configure global parameters
* *
* * The sqlite3session_config ( ) interface is used to make global configuration
* * changes to the sessions module in order to tune it to the specific needs
* * of the application .
* *
* * The sqlite3session_config ( ) interface is not threadsafe . If it is invoked
* * while any other thread is inside any other sessions method then the
* * results are undefined . Furthermore , if it is invoked after any sessions
* * related objects have been created , the results are also undefined .
* *
* * The first argument to the sqlite3session_config ( ) function must be one
* * of the SQLITE_SESSION_CONFIG_XXX constants defined below . The
* * interpretation of the ( void * ) value passed as the second parameter and
* * the effect of calling this function depends on the value of the first
* * parameter .
* *
* * < dl >
* * < dt > SQLITE_SESSION_CONFIG_STRMSIZE < dd >
* * By default , the sessions module streaming interfaces attempt to input
* * and output data in approximately 1 KiB chunks . This operand may be used
* * to set and query the value of this configuration setting . The pointer
* * passed as the second argument must point to a value of type ( int ) .
* * If this value is greater than 0 , it is used as the new streaming data
* * chunk size for both input and output . Before returning , the ( int ) value
* * pointed to by pArg is set to the final value of the streaming interface
* * chunk size .
* * < / dl >
* *
* * This function returns SQLITE_OK if successful , or an SQLite error code
* * otherwise .
*/
int sqlite3session_config ( int op , void * pArg ) ;
/*
* * CAPI3REF : Values for sqlite3session_config ( ) .
*/
# define SQLITE_SESSION_CONFIG_STRMSIZE 1
2014-09-27 12:26:18 +00:00
2011-04-06 23:40:28 +00:00
/*
* * Make sure we can call this stuff from C + + .
*/
# ifdef __cplusplus
}
2011-03-08 19:22:50 +00:00
# endif
2016-05-04 21:06:21 +00:00
# endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */