xref: /netbsd-src/external/public-domain/sqlite/man/sqlite3changeset_apply.3 (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1.Dd March 11, 2017
2.Dt SQLITE3CHANGESET_APPLY 3
3.Os
4.Sh NAME
5.Nm sqlite3changeset_apply
6.Nd Apply A Changeset To A Database
7.Sh SYNOPSIS
8.Ft int
9.Fo sqlite3changeset_apply
10.Fa "sqlite3 *db"
11.Fa "int nChangeset"
12.Fa "void *pChangeset"
13.Fa "int(*xFilter)( void *pCtx,                   const char *zTab              )"
14.Fa "int(*xConflict)( void *pCtx,                   int eConflict,                sqlite3_changeset_iter *p     )"
15.Fa "void *pCtx                      "
16.Fc
17.Sh DESCRIPTION
18Apply a changeset to a database.
19This function attempts to update the "main" database attached to handle
20db with the changes found in the changeset passed via the second and
21third arguments.
22.Pp
23The fourth argument (xFilter) passed to this function is the "filter
24callback".
25If it is not NULL, then for each table affected by at least one change
26in the changeset, the filter callback is invoked with the table name
27as the second argument, and a copy of the context pointer passed as
28the sixth argument to this function as the first.
29If the "filter callback" returns zero, then no attempt is made to apply
30any changes to the table.
31Otherwise, if the return value is non-zero or the xFilter argument
32to this function is NULL, all changes related to the table are attempted.
33.Pp
34For each table that is not excluded by the filter callback, this function
35tests that the target database contains a compatible table.
36A table is considered compatible if all of the following are true:
37.Bl -bullet
38.It
39The table has the same name as the name recorded in the changeset,
40and
41.It
42The table has at least as many columns as recorded in the changeset,
43and
44.It
45The table has primary key columns in the same position as recorded
46in the changeset.
47.El
48.Pp
49If there is no compatible table, it is not an error, but none of the
50changes associated with the table are applied.
51A warning message is issued via the sqlite3_log() mechanism with the
52error code SQLITE_SCHEMA.
53At most one such warning is issued for each table in the changeset.
54.Pp
55For each change for which there is a compatible table, an attempt is
56made to modify the table contents according to the UPDATE, INSERT or
57DELETE change.
58If a change cannot be applied cleanly, the conflict handler function
59passed as the fifth argument to sqlite3changeset_apply() may be invoked.
60A description of exactly when the conflict handler is invoked for each
61type of change is below.
62.Pp
63Unlike the xFilter argument, xConflict may not be passed NULL.
64The results of passing anything other than a valid function pointer
65as the xConflict argument are undefined.
66.Pp
67Each time the conflict handler function is invoked, it must return
68one of SQLITE_CHANGESET_OMIT, SQLITE_CHANGESET_ABORT
69or SQLITE_CHANGESET_REPLACE.
70SQLITE_CHANGESET_REPLACE may only be returned if the second argument
71passed to the conflict handler is either SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT.
72If the conflict-handler returns an illegal value, any changes already
73made are rolled back and the call to sqlite3changeset_apply() returns
74SQLITE_MISUSE.
75Different actions are taken by sqlite3changeset_apply() depending on
76the value returned by each invocation of the conflict-handler function.
77Refer to the documentation for the three available return values
78for details.
79.Bl -tag -width Ds
80.It DELETE ChangesFor each DELETE change, this function checks if the
81target database contains a row with the same primary key value (or
82values) as the original row values stored in the changeset.
83If it does, and the values stored in all non-primary key columns also
84match the values stored in the changeset the row is deleted from the
85target database.
86.Pp
87If a row with matching primary key values is found, but one or more
88of the non-primary key fields contains a value different from the original
89row value stored in the changeset, the conflict-handler function is
90invoked with SQLITE_CHANGESET_DATA as the second
91argument.
92If the database table has more columns than are recorded in the changeset,
93only the values of those non-primary key fields are compared against
94the current database contents - any trailing database table columns
95are ignored.
96.Pp
97If no row with matching primary key values is found in the database,
98the conflict-handler function is invoked with SQLITE_CHANGESET_NOTFOUND
99passed as the second argument.
100.Pp
101If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
102(which can only happen if a foreign key constraint is violated), the
103conflict-handler function is invoked with SQLITE_CHANGESET_CONSTRAINT
104passed as the second argument.
105This includes the case where the DELETE operation is attempted because
106an earlier call to the conflict handler function returned SQLITE_CHANGESET_REPLACE.
107.It INSERT ChangesFor each INSERT change, an attempt is made to insert
108the new row into the database.
109If the changeset row contains fewer fields than the database table,
110the trailing fields are populated with their default values.
111.Pp
112If the attempt to insert the row fails because the database already
113contains a row with the same primary key values, the conflict handler
114function is invoked with the second argument set to SQLITE_CHANGESET_CONFLICT.
115.Pp
116If the attempt to insert the row fails because of some other constraint
117violation (e.g.
118NOT NULL or UNIQUE), the conflict handler function is invoked with
119the second argument set to SQLITE_CHANGESET_CONSTRAINT.
120This includes the case where the INSERT operation is re-attempted because
121an earlier call to the conflict handler function returned SQLITE_CHANGESET_REPLACE.
122.It UPDATE ChangesFor each UPDATE change, this function checks if the
123target database contains a row with the same primary key value (or
124values) as the original row values stored in the changeset.
125If it does, and the values stored in all modified non-primary key columns
126also match the values stored in the changeset the row is updated within
127the target database.
128.Pp
129If a row with matching primary key values is found, but one or more
130of the modified non-primary key fields contains a value different from
131an original row value stored in the changeset, the conflict-handler
132function is invoked with SQLITE_CHANGESET_DATA
133as the second argument.
134Since UPDATE changes only contain values for non-primary key fields
135that are to be modified, only those fields need to match the original
136values to avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
137.Pp
138If no row with matching primary key values is found in the database,
139the conflict-handler function is invoked with SQLITE_CHANGESET_NOTFOUND
140passed as the second argument.
141.Pp
142If the UPDATE operation is attempted, but SQLite returns SQLITE_CONSTRAINT,
143the conflict-handler function is invoked with SQLITE_CHANGESET_CONSTRAINT
144passed as the second argument.
145This includes the case where the UPDATE operation is attempted after
146an earlier call to the conflict handler function returned SQLITE_CHANGESET_REPLACE.
147.El
148.Pp
149It is safe to execute SQL statements, including those that write to
150the table that the callback related to, from within the xConflict callback.
151This can be used to further customize the applications conflict resolution
152strategy.
153.Pp
154All changes made by this function are enclosed in a savepoint transaction.
155If any other error (aside from a constraint failure when attempting
156to write to the target database) occurs, then the savepoint transaction
157is rolled back, restoring the target database to its original state,
158and an SQLite error code returned.
159.Sh SEE ALSO
160.Xr SQLITE_CHANGESET_OMIT 3 ,
161.Xr SQLITE_CHANGESET_DATA 3 ,
162.Xr SQLITE_CHANGESET_OMIT 3
163