1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
.Dd January 24, 2024
.Dt SQLITE3_PREUPDATE_HOOK 3
.Os
.Sh NAME
.Nm sqlite3_preupdate_hook ,
.Nm sqlite3_preupdate_old ,
.Nm sqlite3_preupdate_count ,
.Nm sqlite3_preupdate_depth ,
.Nm sqlite3_preupdate_new ,
.Nm sqlite3_preupdate_blobwrite
.Nd the pre-update hook
.Sh SYNOPSIS
.In sqlite3.h
.Ft void *
.Fo sqlite3_preupdate_hook
.Fa "sqlite3 *db"
.Fa "void(*xPreUpdate)( void *pCtx,sqlite3 *db,int op,char const *zDb,char const *zName,sqlite3_int64 iKey1,sqlite3_int64 iKey2)"
.Fa "void*"
.Fc
.Ft int
.Fo sqlite3_preupdate_old
.Fa "sqlite3 *"
.Fa "int"
.Fa "sqlite3_value **"
.Fc
.Ft int
.Fo sqlite3_preupdate_count
.Fa "sqlite3 *"
.Fc
.Ft int
.Fo sqlite3_preupdate_depth
.Fa "sqlite3 *"
.Fc
.Ft int
.Fo sqlite3_preupdate_new
.Fa "sqlite3 *"
.Fa "int"
.Fa "sqlite3_value **"
.Fc
.Ft int
.Fo sqlite3_preupdate_blobwrite
.Fa "sqlite3 *"
.Fc
.Sh DESCRIPTION
These interfaces are only available if SQLite is compiled using the
SQLITE_ENABLE_PREUPDATE_HOOK compile-time
option.
.Pp
The
.Fn sqlite3_preupdate_hook
interface registers a callback function that is invoked prior to each
INSERT, UPDATE, and DELETE operation on a database
table.
At most one preupdate hook may be registered at a time on a single
database connection; each call to
.Fn sqlite3_preupdate_hook
overrides the previous setting.
The preupdate hook is disabled by invoking
.Fn sqlite3_preupdate_hook
with a NULL pointer as the second parameter.
The third parameter to
.Fn sqlite3_preupdate_hook
is passed through as the first parameter to callbacks.
.Pp
The preupdate hook only fires for changes to real database tables;
the preupdate hook is not invoked for changes to virtual tables
or to system tables like sqlite_sequence or sqlite_stat1.
.Pp
The second parameter to the preupdate callback is a pointer to the
database connection that registered the preupdate
hook.
The third parameter to the preupdate callback is one of the constants
SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE
to identify the kind of update operation that is about to occur.
The fourth parameter to the preupdate callback is the name of the database
within the database connection that is being modified.
This will be "main" for the main database or "temp" for TEMP tables
or the name given after the AS keyword in the ATTACH statement
for attached databases.
The fifth parameter to the preupdate callback is the name of the table
that is being modified.
.Pp
For an UPDATE or DELETE operation on a rowid table, the
sixth parameter passed to the preupdate callback is the initial rowid
of the row being modified or deleted.
For an INSERT operation on a rowid table, or any operation on a WITHOUT
ROWID table, the value of the sixth parameter is undefined.
For an INSERT or UPDATE on a rowid table the seventh parameter is the
final rowid value of the row being inserted or updated.
The value of the seventh parameter passed to the callback function
is not defined for operations on WITHOUT ROWID tables, or for DELETE
operations on rowid tables.
.Pp
The sqlite3_preupdate_hook(D,C,P) function returns the P argument from
the previous call on the same database connection
D, or NULL for the first call on D.
.Pp
The
.Fn sqlite3_preupdate_old ,
.Fn sqlite3_preupdate_new ,
.Fn sqlite3_preupdate_count ,
and
.Fn sqlite3_preupdate_depth
interfaces provide additional information about a preupdate event.
These routines may only be called from within a preupdate callback.
Invoking any of these routines from outside of a preupdate callback
or with a database connection pointer that is different
from the one supplied to the preupdate callback results in undefined
and probably undesirable behavior.
.Pp
The sqlite3_preupdate_count(D) interface
returns the number of columns in the row that is being inserted, updated,
or deleted.
.Pp
The sqlite3_preupdate_old(D,N,P) interface
writes into P a pointer to a protected sqlite3_value
that contains the value of the Nth column of the table row before it
is updated.
The N parameter must be between 0 and one less than the number of columns
or the behavior will be undefined.
This must only be used within SQLITE_UPDATE and SQLITE_DELETE preupdate
callbacks; if it is used by an SQLITE_INSERT callback then the behavior
is undefined.
The sqlite3_value that P points to will be destroyed when
the preupdate callback returns.
.Pp
The sqlite3_preupdate_new(D,N,P) interface
writes into P a pointer to a protected sqlite3_value
that contains the value of the Nth column of the table row after it
is updated.
The N parameter must be between 0 and one less than the number of columns
or the behavior will be undefined.
This must only be used within SQLITE_INSERT and SQLITE_UPDATE preupdate
callbacks; if it is used by an SQLITE_DELETE callback then the behavior
is undefined.
The sqlite3_value that P points to will be destroyed when
the preupdate callback returns.
.Pp
The sqlite3_preupdate_depth(D) interface
returns 0 if the preupdate callback was invoked as a result of a direct
insert, update, or delete operation; or 1 for inserts, updates, or
deletes invoked by top-level triggers; or 2 for changes resulting from
triggers called by top-level triggers; and so forth.
.Pp
When the
.Fn sqlite3_blob_write
API is used to update a blob column, the pre-update hook is invoked
with SQLITE_DELETE.
This is because the in this case the new values are not available.
In this case, when a callback made with op==SQLITE_DELETE is actually
a write using the sqlite3_blob_write() API, the
.Fn sqlite3_preupdate_blobwrite
returns the index of the column being written.
In other cases, where the pre-update hook is being invoked for some
other reason, including a regular DELETE, sqlite3_preupdate_blobwrite()
returns -1.
.Pp
.Sh IMPLEMENTATION NOTES
These declarations were extracted from the
interface documentation at line 10316.
.Bd -literal
#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
SQLITE_API void *sqlite3_preupdate_hook(
sqlite3 *db,
void(*xPreUpdate)(
void *pCtx, /* Copy of third arg to preupdate_hook() */
sqlite3 *db, /* Database handle */
int op, /* SQLITE_UPDATE, DELETE or INSERT */
char const *zDb, /* Database name */
char const *zName, /* Table name */
sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
),
void*
);
SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *);
#endif
.Ed
.Sh SEE ALSO
.Xr sqlite3 3 ,
.Xr sqlite3_blob_write 3 ,
.Xr sqlite3_update_hook 3 ,
.Xr sqlite3_value 3 ,
.Xr SQLITE_CREATE_INDEX 3
|