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