-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
bindings.dart
394 lines (372 loc) · 19.1 KB
/
bindings.dart
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "dart:ffi";
import "package:ffi/ffi.dart";
import "../ffi/dylib_utils.dart";
import "signatures.dart";
import "types.dart";
class _SQLiteBindings {
DynamicLibrary sqlite;
/// Opening A New Database Connection
///
/// ^These routines open an SQLite database file as specified by the
/// filename argument. ^The filename argument is interpreted as UTF-8 for
/// sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
/// order for sqlite3_open16(). ^(A database connection handle is usually
/// returned in *ppDb, even if an error occurs. The only exception is that
/// if SQLite is unable to allocate memory to hold the sqlite3 object,
/// a NULL will be written into *ppDb instead of a pointer to the sqlite3
/// object.)^ ^(If the database is opened (and/or created) successfully, then
/// [SQLITE_OK] is returned. Otherwise an error code is returned.)^ ^The
/// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
/// an English language description of the error following a failure of any
/// of the sqlite3_open() routines.
int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
int Function(Pointer<Database> database) sqlite3_close_v2;
/// Compiling An SQL Statement
///
/// To execute an SQL query, it must first be compiled into a byte-code
/// program using one of these routines.
///
/// The first argument, "db", is a database connection obtained from a
/// prior successful call to sqlite3_open, [sqlite3_open_v2] or
/// sqlite3_open16. The database connection must not have been closed.
///
/// The second argument, "zSql", is the statement to be compiled, encoded
/// as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
/// interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
/// use UTF-16.
///
/// ^If the nByte argument is less than zero, then zSql is read up to the
/// first zero terminator. ^If nByte is non-negative, then it is the maximum
/// number of bytes read from zSql. ^When nByte is non-negative, the
/// zSql string ends at either the first '\000' or '\u0000' character or
/// the nByte-th byte, whichever comes first. If the caller knows
/// that the supplied string is nul-terminated, then there is a small
/// performance advantage to be gained by passing an nByte parameter that
/// is equal to the number of bytes in the input string <i>including</i>
/// the nul-terminator bytes.
///
/// ^If pzTail is not NULL then *pzTail is made to point to the first byte
/// past the end of the first SQL statement in zSql. These routines only
/// compile the first statement in zSql, so *pzTail is left pointing to
/// what remains uncompiled.
///
/// ^*ppStmt is left pointing to a compiled prepared statement that can be
/// executed using sqlite3_step. ^If there is an error, *ppStmt is set
/// to NULL. ^If the input text contains no SQL (if the input is an empty
/// string or a comment) then *ppStmt is set to NULL.
/// The calling procedure is responsible for deleting the compiled
/// SQL statement using [sqlite3_finalize] after it has finished with it.
/// ppStmt may not be NULL.
///
/// ^On success, the sqlite3_prepare family of routines return [SQLITE_OK];
/// otherwise an error code is returned.
///
/// The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
/// recommended for all new programs. The two older interfaces are retained
/// for backwards compatibility, but their use is discouraged.
/// ^In the "v2" interfaces, the prepared statement
/// that is returned (the sqlite3_stmt object) contains a copy of the
/// original SQL text. This causes the [sqlite3_step] interface to
/// behave differently in three ways:
int Function(
Pointer<Database> database,
Pointer<Utf8> query,
int nbytes,
Pointer<Pointer<Statement>> statementOut,
Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
/// Evaluate An SQL Statement
///
/// After a prepared statement has been prepared using either
/// [sqlite3_prepare_v2] or sqlite3_prepare16_v2() or one of the legacy
/// interfaces sqlite3_prepare() or sqlite3_prepare16(), this function
/// must be called one or more times to evaluate the statement.
///
/// The details of the behavior of the sqlite3_step() interface depend
/// on whether the statement was prepared using the newer "v2" interface
/// [sqlite3_prepare_v2] and sqlite3_prepare16_v2() or the older legacy
/// interface sqlite3_prepare() and sqlite3_prepare16(). The use of the
/// new "v2" interface is recommended for new applications but the legacy
/// interface will continue to be supported.
///
/// ^In the legacy interface, the return value will be either [SQLITE_BUSY],
/// [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
/// ^With the "v2" interface, any of the other [result codes] or
/// [extended result codes] might be returned as well.
///
/// ^[SQLITE_BUSY] means that the database engine was unable to acquire the
/// database locks it needs to do its job. ^If the statement is a [COMMIT]
/// or occurs outside of an explicit transaction, then you can retry the
/// statement. If the statement is not a [COMMIT] and occurs within an
/// explicit transaction then you should rollback the transaction before
/// continuing.
///
/// ^[SQLITE_DONE] means that the statement has finished executing
/// successfully. sqlite3_step() should not be called again on this virtual
/// machine without first calling [sqlite3_reset()] to reset the virtual
/// machine back to its initial state.
///
/// ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
/// is returned each time a new row of data is ready for processing by the
/// caller. The values may be accessed using the [column access functions].
/// sqlite3_step() is called again to retrieve the next row of data.
///
/// ^[SQLITE_ERROR] means that a run-time error (such as a constraint
/// violation) has occurred. sqlite3_step() should not be called again on
/// the VM. More information may be found by calling [sqlite3_errmsg()].
/// ^With the legacy interface, a more specific error code (for example,
/// [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
/// can be obtained by calling [sqlite3_reset()] on the
/// prepared statement. ^In the "v2" interface,
/// the more specific error code is returned directly by sqlite3_step().
///
/// [SQLITE_MISUSE] means that the this routine was called inappropriately.
/// Perhaps it was called on a prepared statement that has
/// already been [sqlite3_finalize | finalized] or on one that had
/// previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
/// be the case that the same database connection is being used by two or
/// more threads at the same moment in time.
///
/// For all versions of SQLite up to and including 3.6.23.1, a call to
/// [sqlite3_reset] was required after sqlite3_step() returned anything
/// other than [Errors.SQLITE_ROW] before any subsequent invocation of
/// sqlite3_step(). Failure to reset the prepared statement using
/// [sqlite3_reset()] would result in an [Errors.SQLITE_MISUSE] return from
/// sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
/// calling [sqlite3_reset] automatically in this circumstance rather
/// than returning [Errors.SQLITE_MISUSE]. This is not considered a
/// compatibility break because any application that ever receives an
/// [Errors.SQLITE_MISUSE] error is broken by definition. The
/// [SQLITE_OMIT_AUTORESET] compile-time option
/// can be used to restore the legacy behavior.
///
/// <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
/// API always returns a generic error code, [SQLITE_ERROR], following any
/// error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
/// [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
/// specific [error codes] that better describes the error.
/// We admit that this is a goofy design. The problem has been fixed
/// with the "v2" interface. If you prepare all of your SQL statements
/// using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
/// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
/// then the more specific [error codes] are returned directly
/// by sqlite3_step(). The use of the "v2" interface is recommended.
int Function(Pointer<Statement> statement) sqlite3_step;
/// CAPI3REF: Reset A Prepared Statement Object
///
/// The sqlite3_reset() function is called to reset a prepared statement
/// object back to its initial state, ready to be re-executed.
/// ^Any SQL statement variables that had values bound to them using
/// the sqlite3_bind_blob | sqlite3_bind_*() API retain their values.
/// Use sqlite3_clear_bindings() to reset the bindings.
///
/// ^The [sqlite3_reset] interface resets the prepared statement S
/// back to the beginning of its program.
///
/// ^If the most recent call to [sqlite3_step] for the
/// prepared statement S returned [Errors.SQLITE_ROW] or [Errors.SQLITE_DONE],
/// or if [sqlite3_step] has never before been called on S,
/// then [sqlite3_reset] returns [Errors.SQLITE_OK].
///
/// ^If the most recent call to [sqlite3_step(S)] for the
/// prepared statement S indicated an error, then
/// [sqlite3_reset] returns an appropriate [Errors].
///
/// ^The [sqlite3_reset] interface does not change the values
int Function(Pointer<Statement> statement) sqlite3_reset;
/// Destroy A Prepared Statement Object
///
/// ^The sqlite3_finalize() function is called to delete a prepared statement.
/// ^If the most recent evaluation of the statement encountered no errors
/// or if the statement is never been evaluated, then sqlite3_finalize()
/// returns SQLITE_OK. ^If the most recent evaluation of statement S failed,
/// then sqlite3_finalize(S) returns the appropriate error code or extended
/// error code.
///
/// ^The sqlite3_finalize(S) routine can be called at any point during
/// the life cycle of prepared statement S:
/// before statement S is ever evaluated, after
/// one or more calls to [sqlite3_reset], or after any call
/// to [sqlite3_step] regardless of whether or not the statement has
/// completed execution.
///
/// ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
///
/// The application must finalize every prepared statement in order to avoid
/// resource leaks. It is a grievous error for the application to try to use
/// a prepared statement after it has been finalized. Any use of a prepared
/// statement after it has been finalized can result in undefined and
/// undesirable behavior such as segfaults and heap corruption.
int Function(Pointer<Statement> statement) sqlite3_finalize;
/// Number Of Columns In A Result Set
///
/// ^Return the number of columns in the result set returned by the
/// prepared statement. ^This routine returns 0 if pStmt is an SQL
/// statement that does not return data (for example an [UPDATE]).
int Function(Pointer<Statement> statement) sqlite3_column_count;
/// Column Names In A Result Set
///
/// ^These routines return the name assigned to a particular column
/// in the result set of a SELECT statement. ^The sqlite3_column_name()
/// interface returns a pointer to a zero-terminated UTF-8 string
/// and sqlite3_column_name16() returns a pointer to a zero-terminated
/// UTF-16 string. ^The first parameter is the prepared statement
/// that implements the SELECT statement. ^The second parameter is the
/// column number. ^The leftmost column is number 0.
///
/// ^The returned string pointer is valid until either the prepared statement
/// is destroyed by [sqlite3_finalize] or until the statement is automatically
/// reprepared by the first call to [sqlite3_step] for a particular run
/// or until the next call to
/// sqlite3_column_name() or sqlite3_column_name16() on the same column.
///
/// ^If sqlite3_malloc() fails during the processing of either routine
/// (for example during a conversion from UTF-8 to UTF-16) then a
/// NULL pointer is returned.
///
/// ^The name of a result column is the value of the "AS" clause for
/// that column, if there is an AS clause. If there is no AS clause
/// then the name of the column is unspecified and may change from
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_name;
/// CAPI3REF: Declared Datatype Of A Query Result
///
/// ^(The first parameter is a prepared statement.
/// If this statement is a SELECT statement and the Nth column of the
/// returned result set of that SELECT is a table column (not an
/// expression or subquery) then the declared type of the table
/// column is returned.)^ ^If the Nth column of the result set is an
/// expression or subquery, then a NULL pointer is returned.
/// ^The returned string is always UTF-8 encoded.
///
/// ^(For example, given the database schema:
///
/// CREATE TABLE t1(c1 VARIANT);
///
/// and the following statement to be compiled:
///
/// SELECT c1 + 1, c1 FROM t1;
///
/// this routine would return the string "VARIANT" for the second result
/// column (i==1), and a NULL pointer for the first result column (i==0).)^
///
/// ^SQLite uses dynamic run-time typing. ^So just because a column
/// is declared to contain a particular type does not mean that the
/// data stored in that column is of the declared type. SQLite is
/// strongly typed, but the typing is dynamic not static. ^Type
/// is associated with individual values, not with the containers
/// used to hold those values.
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_decltype;
int Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_type;
Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_value;
double Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_double;
int Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_int;
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_text;
/// The sqlite3_errstr() interface returns the English-language text that
/// describes the result code, as UTF-8. Memory to hold the error message
/// string is managed internally and must not be freed by the application.
Pointer<Utf8> Function(int code) sqlite3_errstr;
/// Error Codes And Messages
///
/// ^The sqlite3_errcode() interface returns the numeric [result code] or
/// [extended result code] for the most recent failed sqlite3_* API call
/// associated with a [database connection]. If a prior API call failed
/// but the most recent API call succeeded, the return value from
/// sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode()
/// interface is the same except that it always returns the
/// [extended result code] even when extended result codes are
/// disabled.
///
/// ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
/// text that describes the error, as either UTF-8 or UTF-16 respectively.
/// ^(Memory to hold the error message string is managed internally.
/// The application does not need to worry about freeing the result.
/// However, the error string might be overwritten or deallocated by
/// subsequent calls to other SQLite interface functions.)^
///
/// When the serialized [threading mode] is in use, it might be the
/// case that a second error occurs on a separate thread in between
/// the time of the first error and the call to these interfaces.
/// When that happens, the second error will be reported since these
/// interfaces always report the most recent result. To avoid
/// this, each thread can obtain exclusive use of the [database connection] D
/// by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
/// to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
/// all calls to the interfaces listed here are completed.
///
/// If an interface fails with SQLITE_MISUSE, that means the interface
/// was invoked incorrectly by the application. In that case, the
/// error code and message may or may not be set.
Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
_SQLiteBindings() {
sqlite = dlopenPlatformSpecific("sqlite3");
sqlite3_open_v2 = sqlite
.lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
.asFunction();
sqlite3_close_v2 = sqlite
.lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
.asFunction();
sqlite3_prepare_v2 = sqlite
.lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
"sqlite3_prepare_v2")
.asFunction();
sqlite3_step = sqlite
.lookup<NativeFunction<sqlite3_step_native_t>>("sqlite3_step")
.asFunction();
sqlite3_reset = sqlite
.lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
.asFunction();
sqlite3_finalize = sqlite
.lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
.asFunction();
sqlite3_errstr = sqlite
.lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
.asFunction();
sqlite3_errmsg = sqlite
.lookup<NativeFunction<sqlite3_errmsg_native_t>>("sqlite3_errmsg")
.asFunction();
sqlite3_column_count = sqlite
.lookup<NativeFunction<sqlite3_column_count_native_t>>(
"sqlite3_column_count")
.asFunction();
sqlite3_column_name = sqlite
.lookup<NativeFunction<sqlite3_column_name_native_t>>(
"sqlite3_column_name")
.asFunction();
sqlite3_column_decltype = sqlite
.lookup<NativeFunction<sqlite3_column_decltype_native_t>>(
"sqlite3_column_decltype")
.asFunction();
sqlite3_column_type = sqlite
.lookup<NativeFunction<sqlite3_column_type_native_t>>(
"sqlite3_column_type")
.asFunction();
sqlite3_column_value = sqlite
.lookup<NativeFunction<sqlite3_column_value_native_t>>(
"sqlite3_column_value")
.asFunction();
sqlite3_column_double = sqlite
.lookup<NativeFunction<sqlite3_column_double_native_t>>(
"sqlite3_column_double")
.asFunction();
sqlite3_column_int = sqlite
.lookup<NativeFunction<sqlite3_column_int_native_t>>(
"sqlite3_column_int")
.asFunction();
sqlite3_column_text = sqlite
.lookup<NativeFunction<sqlite3_column_text_native_t>>(
"sqlite3_column_text")
.asFunction();
}
}
_SQLiteBindings _cachedBindings;
_SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();