mirror of
https://github.com/openai/codex.git
synced 2026-10-21 17:48:44 +00:00
Replace vendored SQLite fix with blocked dependency placeholder
Do not carry SQLite amalgamation source in Codex. Leave the draft blocked on selecting an owner for a pinned external sqlx-sqlite 0.8.6 patch that can admit fixed libsqlite3-sys releases.
This commit is contained in:
@@ -8,7 +8,3 @@ codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.js
|
||||
codex-rs/tui/tests/fixtures/oss-story.jsonl
|
||||
codex-rs/tui_app_server/tests/fixtures/oss-story.jsonl
|
||||
codex-rs/tui/src/app.rs
|
||||
third_party/libsqlite3-sys/sqlcipher/sqlite3.c
|
||||
third_party/libsqlite3-sys/sqlcipher/sqlite3.h
|
||||
third_party/libsqlite3-sys/sqlite3/sqlite3.c
|
||||
third_party/libsqlite3-sys/sqlite3/sqlite3.h
|
||||
|
||||
Generated
+1
-1
@@ -1173,6 +1173,7 @@
|
||||
"libm_0.2.16": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"no-panic\",\"req\":\"^0.1.35\"}],\"features\":{\"arch\":[],\"default\":[\"arch\"],\"force-soft-floats\":[],\"unstable\":[\"unstable-intrinsics\",\"unstable-float\"],\"unstable-float\":[],\"unstable-intrinsics\":[],\"unstable-public-internals\":[]}}",
|
||||
"libredox_0.1.12": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2\"},{\"name\":\"ioslice\",\"optional\":true,\"req\":\"^0.6\"},{\"name\":\"libc\",\"req\":\"^0.2\"},{\"name\":\"redox_syscall\",\"optional\":true,\"req\":\"^0.7\"}],\"features\":{\"call\":[],\"default\":[\"call\",\"std\",\"redox_syscall\"],\"mkns\":[\"ioslice\"],\"std\":[]}}",
|
||||
"libredox_0.1.14": "{\"dependencies\":[{\"name\":\"bitflags\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"ioslice\",\"optional\":true,\"req\":\"^0.6\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"plain\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"redox_syscall\",\"optional\":true,\"req\":\"^0.7\"}],\"features\":{\"base\":[\"libc\"],\"call\":[\"base\"],\"default\":[\"base\",\"call\",\"std\",\"redox_syscall\",\"protocol\"],\"mkns\":[\"ioslice\"],\"protocol\":[\"plain\",\"bitflags\",\"redox_syscall\"],\"std\":[\"base\"]}}",
|
||||
"libsqlite3-sys_0.30.1": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"runtime\"],\"kind\":\"build\",\"name\":\"bindgen\",\"optional\":true,\"req\":\"^0.69\"},{\"kind\":\"build\",\"name\":\"cc\",\"optional\":true,\"req\":\"^1.1.6\"},{\"name\":\"openssl-sys\",\"optional\":true,\"req\":\"^0.9.103\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"optional\":true,\"req\":\"^0.3.19\"},{\"kind\":\"build\",\"name\":\"prettyplease\",\"optional\":true,\"req\":\"^0.2.20\"},{\"default_features\":false,\"kind\":\"build\",\"name\":\"quote\",\"optional\":true,\"req\":\"^1.0.36\"},{\"features\":[\"full\",\"extra-traits\",\"visit-mut\"],\"kind\":\"build\",\"name\":\"syn\",\"optional\":true,\"req\":\"^2.0.72\"},{\"kind\":\"build\",\"name\":\"vcpkg\",\"optional\":true,\"req\":\"^0.2.15\"}],\"features\":{\"buildtime_bindgen\":[\"bindgen\",\"pkg-config\",\"vcpkg\"],\"bundled\":[\"cc\",\"bundled_bindings\"],\"bundled-sqlcipher\":[\"bundled\"],\"bundled-sqlcipher-vendored-openssl\":[\"bundled-sqlcipher\",\"openssl-sys/vendored\"],\"bundled-windows\":[\"cc\",\"bundled_bindings\"],\"bundled_bindings\":[],\"default\":[\"min_sqlite_version_3_14_0\"],\"in_gecko\":[],\"loadable_extension\":[\"prettyplease\",\"quote\",\"syn\"],\"min_sqlite_version_3_14_0\":[\"pkg-config\",\"vcpkg\"],\"preupdate_hook\":[\"buildtime_bindgen\"],\"session\":[\"preupdate_hook\",\"buildtime_bindgen\"],\"sqlcipher\":[],\"unlock_notify\":[],\"wasm32-wasi-vfs\":[],\"with-asan\":[]}}",
|
||||
"libssh2-sys_0.3.1": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.0.25\"},{\"name\":\"libc\",\"req\":\"^0.2\"},{\"default_features\":false,\"features\":[\"libc\"],\"name\":\"libz-sys\",\"req\":\"^1.1.0\"},{\"name\":\"openssl-sys\",\"req\":\"^0.9.35\",\"target\":\"cfg(unix)\"},{\"name\":\"openssl-sys\",\"optional\":true,\"req\":\"^0.9.35\",\"target\":\"cfg(windows)\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"req\":\"^0.3.11\"},{\"kind\":\"build\",\"name\":\"vcpkg\",\"req\":\"^0.2\",\"target\":\"cfg(target_env = \\\"msvc\\\")\"}],\"features\":{\"openssl-on-win32\":[\"openssl-sys\"],\"vendored-openssl\":[\"openssl-sys/vendored\"],\"zlib-ng-compat\":[\"libz-sys/zlib-ng\"]}}",
|
||||
"libz-sys_1.1.23": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.0.98\"},{\"kind\":\"build\",\"name\":\"cmake\",\"optional\":true,\"req\":\"^0.1.50\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.43\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"req\":\"^0.3.9\"},{\"kind\":\"build\",\"name\":\"vcpkg\",\"req\":\"^0.2.11\"}],\"features\":{\"asm\":[],\"default\":[\"libc\",\"stock-zlib\"],\"static\":[],\"stock-zlib\":[],\"zlib-ng\":[\"libc\",\"cmake\"],\"zlib-ng-no-cmake-experimental-community-maintained\":[\"libc\"]}}",
|
||||
"libz-sys_1.1.25": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.0.98\"},{\"kind\":\"build\",\"name\":\"cmake\",\"optional\":true,\"req\":\"^0.1.50\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.43\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"req\":\"^0.3.9\"},{\"kind\":\"build\",\"name\":\"vcpkg\",\"req\":\"^0.2.11\"}],\"features\":{\"asm\":[],\"default\":[\"libc\",\"stock-zlib\"],\"static\":[],\"stock-zlib\":[],\"zlib-ng\":[\"libc\",\"cmake\"],\"zlib-ng-no-cmake-experimental-community-maintained\":[\"libc\"]}}",
|
||||
@@ -1301,7 +1302,6 @@
|
||||
"password-hash_0.4.2": "{\"dependencies\":[{\"name\":\"base64ct\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2\"}],\"features\":{\"alloc\":[\"base64ct/alloc\"],\"default\":[\"rand_core\"],\"std\":[\"alloc\",\"base64ct/std\",\"rand_core/std\"]}}",
|
||||
"paste_1.0.15": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"paste-test-suite\",\"req\":\"^0\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.49\"}],\"features\":{}}",
|
||||
"pastey_0.2.1": "{\"dependencies\":[],\"features\":{}}",
|
||||
"path+crates/../third_party/libsqlite3-sys_libsqlite3-sys": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"openssl-sys\",\"optional\":true},{\"default_features\":false,\"features\":[\"runtime\"],\"kind\":\"build\",\"name\":\"bindgen\",\"optional\":true},{\"default_features\":true,\"features\":[],\"kind\":\"build\",\"name\":\"cc\",\"optional\":true},{\"default_features\":true,\"features\":[],\"kind\":\"build\",\"name\":\"pkg-config\",\"optional\":true},{\"default_features\":true,\"features\":[],\"kind\":\"build\",\"name\":\"prettyplease\",\"optional\":true},{\"default_features\":false,\"features\":[],\"kind\":\"build\",\"name\":\"quote\",\"optional\":true},{\"default_features\":true,\"features\":[\"full\",\"extra-traits\",\"visit-mut\"],\"kind\":\"build\",\"name\":\"syn\",\"optional\":true},{\"default_features\":true,\"features\":[],\"kind\":\"build\",\"name\":\"vcpkg\",\"optional\":true}],\"features\":{\"buildtime_bindgen\":[\"bindgen\",\"pkg-config\",\"vcpkg\"],\"bundled\":[\"cc\",\"bundled_bindings\"],\"bundled-sqlcipher\":[\"bundled\"],\"bundled-sqlcipher-vendored-openssl\":[\"bundled-sqlcipher\",\"openssl-sys/vendored\"],\"bundled-windows\":[\"cc\",\"bundled_bindings\"],\"bundled_bindings\":[],\"default\":[\"min_sqlite_version_3_14_0\"],\"in_gecko\":[],\"loadable_extension\":[\"prettyplease\",\"quote\",\"syn\"],\"min_sqlite_version_3_14_0\":[\"pkg-config\",\"vcpkg\"],\"preupdate_hook\":[\"buildtime_bindgen\"],\"session\":[\"preupdate_hook\",\"buildtime_bindgen\"],\"sqlcipher\":[],\"unlock_notify\":[],\"wasm32-wasi-vfs\":[],\"with-asan\":[]},\"strip_prefix\":\"\"}",
|
||||
"path-absolutize_3.1.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"name\":\"path-dedot\",\"req\":\"^3.1.1\"},{\"kind\":\"dev\",\"name\":\"slash-formatter\",\"req\":\"^3\",\"target\":\"cfg(windows)\"}],\"features\":{\"lazy_static_cache\":[\"path-dedot/lazy_static_cache\"],\"once_cell_cache\":[\"path-dedot/once_cell_cache\"],\"unsafe_cache\":[\"path-dedot/unsafe_cache\"],\"use_unix_paths_on_wasm\":[\"path-dedot/use_unix_paths_on_wasm\"]}}",
|
||||
"path-dedot_3.1.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"name\":\"lazy_static\",\"optional\":true,\"req\":\"^1.4\"},{\"name\":\"once_cell\",\"req\":\"^1.4\"}],\"features\":{\"lazy_static_cache\":[\"lazy_static\"],\"once_cell_cache\":[],\"unsafe_cache\":[],\"use_unix_paths_on_wasm\":[]}}",
|
||||
"pathdiff_0.2.3": "{\"dependencies\":[{\"name\":\"camino\",\"optional\":true,\"req\":\"^1.0.5\"},{\"kind\":\"dev\",\"name\":\"cfg-if\",\"req\":\"^1.0.0\"}],\"features\":{}}",
|
||||
|
||||
Generated
+2
@@ -8342,6 +8342,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
|
||||
+4
-4
@@ -515,10 +515,10 @@ inherits = "test"
|
||||
opt-level = 0
|
||||
|
||||
[patch.crates-io]
|
||||
# sqlx-sqlite 0.8.6 requires libsqlite3-sys ^0.30.1, whose bundled SQLite
|
||||
# predates the WAL-reset corruption fix. Keep its compatible Rust API while
|
||||
# bundling the fixed SQLite source documented in ../third_party/libsqlite3-sys/UPSTREAM.md.
|
||||
libsqlite3-sys = { path = "../third_party/libsqlite3-sys" }
|
||||
# TODO(sqlite-wal-reset): Use a pinned external sqlx-sqlite 0.8.6 patch that
|
||||
# permits libsqlite3-sys 0.37.0 (bundled SQLite 3.51.3+) once its owning
|
||||
# repository is selected. Pooled WAL-mode state DBs remain exposed while
|
||||
# bundled SQLite 3.46.0 is shipped.
|
||||
# Uncomment to debug local changes.
|
||||
# ratatui = { path = "../../ratatui" }
|
||||
crossterm = { git = "https://github.com/nornagon/crossterm", rev = "87db8bfa6dc99427fd3b071681b07fc31c6ce995" }
|
||||
|
||||
@@ -569,36 +569,6 @@ mod tests {
|
||||
let _ = tokio::fs::remove_dir_all(codex_home).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn linked_sqlite_has_wal_reset_bug_fix() {
|
||||
let pool = SqlitePool::connect("sqlite::memory:")
|
||||
.await
|
||||
.expect("open in-memory sqlite db");
|
||||
let sqlite_version: String = sqlx::query_scalar("SELECT sqlite_version()")
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.expect("query linked sqlite version");
|
||||
pool.close().await;
|
||||
|
||||
let version = sqlite_version
|
||||
.split('.')
|
||||
.map(|part| part.parse::<u32>().expect("numeric sqlite version"))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
version.len(),
|
||||
3,
|
||||
"unexpected SQLite version: {sqlite_version}"
|
||||
);
|
||||
let version = (version[0], version[1], version[2]);
|
||||
let includes_wal_reset_fix = version >= (3, 51, 3)
|
||||
|| (version.0 == 3 && version.1 == 50 && version.2 >= 7)
|
||||
|| (version.0 == 3 && version.1 == 44 && version.2 >= 6);
|
||||
assert!(
|
||||
includes_wal_reset_fix,
|
||||
"linked SQLite {sqlite_version} is vulnerable to the WAL-reset corruption bug"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn open_state_sqlite_tolerates_newer_applied_migrations() {
|
||||
let codex_home = unique_temp_dir();
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"git": {
|
||||
"sha1": "499cc7bb986e04cc66e6ed762522f7ea449178d1"
|
||||
},
|
||||
"path_in_vcs": "libsqlite3-sys"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
/target/
|
||||
/doc/
|
||||
Cargo.lock
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
authors = ["The rusqlite developers"]
|
||||
build = "build.rs"
|
||||
links = "sqlite3"
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = "Native bindings to the libsqlite3 library"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"sqlite",
|
||||
"sqlcipher",
|
||||
"ffi",
|
||||
]
|
||||
categories = ["external-ffi-bindings"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/rusqlite/rusqlite"
|
||||
|
||||
[lib]
|
||||
name = "libsqlite3_sys"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.openssl-sys]
|
||||
version = "0.9.103"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.bindgen]
|
||||
version = "0.69"
|
||||
features = ["runtime"]
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[build-dependencies.cc]
|
||||
version = "1.1.6"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.pkg-config]
|
||||
version = "0.3.19"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.prettyplease]
|
||||
version = "0.2.20"
|
||||
optional = true
|
||||
|
||||
[build-dependencies.quote]
|
||||
version = "1.0.36"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[build-dependencies.syn]
|
||||
version = "2.0.72"
|
||||
features = [
|
||||
"full",
|
||||
"extra-traits",
|
||||
"visit-mut",
|
||||
]
|
||||
optional = true
|
||||
|
||||
[build-dependencies.vcpkg]
|
||||
version = "0.2.15"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
buildtime_bindgen = [
|
||||
"bindgen",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
bundled = [
|
||||
"cc",
|
||||
"bundled_bindings",
|
||||
]
|
||||
bundled-sqlcipher = ["bundled"]
|
||||
bundled-sqlcipher-vendored-openssl = [
|
||||
"bundled-sqlcipher",
|
||||
"openssl-sys/vendored",
|
||||
]
|
||||
bundled-windows = [
|
||||
"cc",
|
||||
"bundled_bindings",
|
||||
]
|
||||
bundled_bindings = []
|
||||
default = ["min_sqlite_version_3_14_0"]
|
||||
in_gecko = []
|
||||
loadable_extension = [
|
||||
"prettyplease",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
min_sqlite_version_3_14_0 = [
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
preupdate_hook = ["buildtime_bindgen"]
|
||||
session = [
|
||||
"preupdate_hook",
|
||||
"buildtime_bindgen",
|
||||
]
|
||||
sqlcipher = []
|
||||
unlock_notify = []
|
||||
wasm32-wasi-vfs = []
|
||||
with-asan = []
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
[package]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
authors = ["The rusqlite developers"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/rusqlite/rusqlite"
|
||||
description = "Native bindings to the libsqlite3 library"
|
||||
license = "MIT"
|
||||
links = "sqlite3"
|
||||
build = "build.rs"
|
||||
keywords = ["sqlite", "sqlcipher", "ffi"]
|
||||
categories = ["external-ffi-bindings"]
|
||||
|
||||
[features]
|
||||
default = ["min_sqlite_version_3_14_0"]
|
||||
bundled = ["cc", "bundled_bindings"]
|
||||
bundled-windows = ["cc", "bundled_bindings"]
|
||||
bundled-sqlcipher = ["bundled"]
|
||||
bundled-sqlcipher-vendored-openssl = ["bundled-sqlcipher", "openssl-sys/vendored"]
|
||||
buildtime_bindgen = ["bindgen", "pkg-config", "vcpkg"]
|
||||
sqlcipher = []
|
||||
min_sqlite_version_3_14_0 = ["pkg-config", "vcpkg"]
|
||||
# Bundle only the bindings file. Note that this does nothing if
|
||||
# `buildtime_bindgen` is enabled.
|
||||
bundled_bindings = []
|
||||
loadable_extension = ["prettyplease", "quote", "syn"]
|
||||
# sqlite3_unlock_notify >= 3.6.12
|
||||
unlock_notify = []
|
||||
# 3.13.0
|
||||
preupdate_hook = ["buildtime_bindgen"]
|
||||
# 3.13.0
|
||||
session = ["preupdate_hook", "buildtime_bindgen"]
|
||||
in_gecko = []
|
||||
with-asan = []
|
||||
wasm32-wasi-vfs = []
|
||||
|
||||
[dependencies]
|
||||
openssl-sys = { version = "0.9.103", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = { version = "0.69", optional = true, default-features = false, features = ["runtime"] }
|
||||
pkg-config = { version = "0.3.19", optional = true }
|
||||
cc = { version = "1.1.6", optional = true }
|
||||
vcpkg = { version = "0.2.15", optional = true }
|
||||
# for loadable_extension:
|
||||
prettyplease = {version = "0.2.20", optional = true }
|
||||
# like bindgen
|
||||
quote = { version = "1.0.36", optional = true, default-features = false }
|
||||
# like bindgen
|
||||
syn = { version = "2.0.72", optional = true, features = ["full", "extra-traits", "visit-mut"] }
|
||||
Vendored
-19
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2014-2021 The rusqlite developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Vendored
-247
@@ -1,247 +0,0 @@
|
||||
# Rusqlite
|
||||
|
||||
[](https://crates.io/crates/rusqlite)
|
||||
[](https://docs.rs/rusqlite)
|
||||
[](https://github.com/rusqlite/rusqlite/actions)
|
||||
[](https://ci.appveyor.com/project/rusqlite/rusqlite)
|
||||
[](https://codecov.io/gh/rusqlite/rusqlite)
|
||||
[](https://deps.rs/repo/github/rusqlite/rusqlite)
|
||||
[](https://discord.gg/nFYfGPB8g4)
|
||||
|
||||
Rusqlite is an ergonomic wrapper for using SQLite from Rust.
|
||||
|
||||
Historically, the API was based on the one from [`rust-postgres`](https://github.com/sfackler/rust-postgres). However, the two have diverged in many ways, and no compatibility between the two is intended.
|
||||
|
||||
## Usage
|
||||
|
||||
In your Cargo.toml:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
# `bundled` causes us to automatically compile and link in an up to date
|
||||
# version of SQLite for you. This avoids many common build issues, and
|
||||
# avoids depending on the version of SQLite on the users system (or your
|
||||
# system), which may be old or missing. It's the right choice for most
|
||||
# programs that control their own SQLite databases.
|
||||
#
|
||||
# That said, it's not ideal for all scenarios and in particular, generic
|
||||
# libraries built around `rusqlite` should probably not enable it, which
|
||||
# is why it is not a default feature -- it could become hard to disable.
|
||||
rusqlite = { version = "0.32.0", features = ["bundled"] }
|
||||
```
|
||||
|
||||
Simple example usage:
|
||||
|
||||
```rust
|
||||
use rusqlite::{Connection, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Person {
|
||||
id: i32,
|
||||
name: String,
|
||||
data: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let conn = Connection::open_in_memory()?;
|
||||
|
||||
conn.execute(
|
||||
"CREATE TABLE person (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
data BLOB
|
||||
)",
|
||||
(), // empty list of parameters.
|
||||
)?;
|
||||
let me = Person {
|
||||
id: 0,
|
||||
name: "Steven".to_string(),
|
||||
data: None,
|
||||
};
|
||||
conn.execute(
|
||||
"INSERT INTO person (name, data) VALUES (?1, ?2)",
|
||||
(&me.name, &me.data),
|
||||
)?;
|
||||
|
||||
let mut stmt = conn.prepare("SELECT id, name, data FROM person")?;
|
||||
let person_iter = stmt.query_map([], |row| {
|
||||
Ok(Person {
|
||||
id: row.get(0)?,
|
||||
name: row.get(1)?,
|
||||
data: row.get(2)?,
|
||||
})
|
||||
})?;
|
||||
|
||||
for person in person_iter {
|
||||
println!("Found person {:?}", person.unwrap());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Supported SQLite Versions
|
||||
|
||||
The base `rusqlite` package supports SQLite version 3.14.0 or newer. If you need
|
||||
support for older versions, please file an issue. Some cargo features require a
|
||||
newer SQLite version; see details below.
|
||||
|
||||
### Optional Features
|
||||
|
||||
Rusqlite provides several features that are behind [Cargo
|
||||
features](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section). They are:
|
||||
|
||||
* [`load_extension`](https://docs.rs/rusqlite/~0/rusqlite/struct.LoadExtensionGuard.html)
|
||||
allows loading dynamic library-based SQLite extensions.
|
||||
* `loadable_extension` to program [loadable extension](https://sqlite.org/loadext.html) in Rust.
|
||||
* [`backup`](https://docs.rs/rusqlite/~0/rusqlite/backup/index.html)
|
||||
allows use of SQLite's online backup API.
|
||||
* [`functions`](https://docs.rs/rusqlite/~0/rusqlite/functions/index.html)
|
||||
allows you to load Rust closures into SQLite connections for use in queries.
|
||||
* `window` for [window function](https://www.sqlite.org/windowfunctions.html) support (`fun(...) OVER ...`). (Implies `functions`.)
|
||||
* [`trace`](https://docs.rs/rusqlite/~0/rusqlite/trace/index.html)
|
||||
allows hooks into SQLite's tracing and profiling APIs.
|
||||
* [`blob`](https://docs.rs/rusqlite/~0/rusqlite/blob/index.html)
|
||||
gives `std::io::{Read, Write, Seek}` access to SQL BLOBs.
|
||||
* [`limits`](https://docs.rs/rusqlite/~0/rusqlite/struct.Connection.html#method.limit)
|
||||
allows you to set and retrieve SQLite's per connection limits.
|
||||
* `chrono` implements [`FromSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.FromSql.html)
|
||||
and [`ToSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.ToSql.html) for various
|
||||
types from the [`chrono` crate](https://crates.io/crates/chrono).
|
||||
* `serde_json` implements [`FromSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.FromSql.html)
|
||||
and [`ToSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.ToSql.html) for the
|
||||
`Value` type from the [`serde_json` crate](https://crates.io/crates/serde_json).
|
||||
* `time` implements [`FromSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.FromSql.html)
|
||||
and [`ToSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.ToSql.html) for various
|
||||
types from the [`time` crate](https://crates.io/crates/time).
|
||||
* `url` implements [`FromSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.FromSql.html)
|
||||
and [`ToSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.ToSql.html) for the
|
||||
`Url` type from the [`url` crate](https://crates.io/crates/url).
|
||||
* `bundled` uses a bundled version of SQLite. This is a good option for cases where linking to SQLite is complicated, such as Windows.
|
||||
* `sqlcipher` looks for the SQLCipher library to link against instead of SQLite. This feature overrides `bundled`.
|
||||
* `bundled-sqlcipher` uses a bundled version of SQLCipher. This searches for and links against a system-installed crypto library to provide the crypto implementation.
|
||||
* `bundled-sqlcipher-vendored-openssl` allows using bundled-sqlcipher with a vendored version of OpenSSL (via the `openssl-sys` crate) as the crypto provider.
|
||||
- As the name implies this depends on the `bundled-sqlcipher` feature, and automatically turns it on.
|
||||
- If turned on, this uses the [`openssl-sys`](https://crates.io/crates/openssl-sys) crate, with the `vendored` feature enabled in order to build and bundle the OpenSSL crypto library.
|
||||
* `hooks` for [Commit, Rollback](http://sqlite.org/c3ref/commit_hook.html) and [Data Change](http://sqlite.org/c3ref/update_hook.html) notification callbacks.
|
||||
* `preupdate_hook` for [preupdate](https://sqlite.org/c3ref/preupdate_count.html) notification callbacks. (Implies `hooks`.)
|
||||
* `unlock_notify` for [Unlock](https://sqlite.org/unlock_notify.html) notification.
|
||||
* `vtab` for [virtual table](https://sqlite.org/vtab.html) support (allows you to write virtual table implementations in Rust). Currently, only read-only virtual tables are supported.
|
||||
* `series` exposes [`generate_series(...)`](https://www.sqlite.org/series.html) Table-Valued Function. (Implies `vtab`.)
|
||||
* [`csvtab`](https://sqlite.org/csv.html), CSV virtual table written in Rust. (Implies `vtab`.)
|
||||
* [`array`](https://sqlite.org/carray.html), The `rarray()` Table-Valued Function. (Implies `vtab`.)
|
||||
* `i128_blob` allows storing values of type `i128` type in SQLite databases. Internally, the data is stored as a 16 byte big-endian blob, with the most significant bit flipped, which allows ordering and comparison between different blobs storing i128s to work as expected.
|
||||
* `uuid` allows storing and retrieving `Uuid` values from the [`uuid`](https://docs.rs/uuid/) crate using blobs.
|
||||
* [`session`](https://sqlite.org/sessionintro.html), Session module extension. Requires `buildtime_bindgen` feature. (Implies `hooks`.)
|
||||
* `extra_check` fail when a query passed to execute is readonly or has a column count > 0.
|
||||
* `column_decltype` provides `columns()` method for Statements and Rows; omit if linking to a version of SQLite/SQLCipher compiled with `-DSQLITE_OMIT_DECLTYPE`.
|
||||
* `collation` exposes [`sqlite3_create_collation_v2`](https://sqlite.org/c3ref/create_collation.html).
|
||||
* `serialize` exposes [`sqlite3_serialize`](http://sqlite.org/c3ref/serialize.html) (3.23.0).
|
||||
|
||||
## Notes on building rusqlite and libsqlite3-sys
|
||||
|
||||
`libsqlite3-sys` is a separate crate from `rusqlite` that provides the Rust
|
||||
declarations for SQLite's C API. By default, `libsqlite3-sys` attempts to find a SQLite library that already exists on your system using pkg-config, or a
|
||||
[Vcpkg](https://github.com/Microsoft/vcpkg) installation for MSVC ABI builds.
|
||||
|
||||
You can adjust this behavior in a number of ways:
|
||||
|
||||
* If you use the `bundled`, `bundled-sqlcipher`, or `bundled-sqlcipher-vendored-openssl` features, `libsqlite3-sys` will use the
|
||||
[cc](https://crates.io/crates/cc) crate to compile SQLite or SQLCipher from source and
|
||||
link against that. This source is embedded in the `libsqlite3-sys` crate and
|
||||
is currently SQLite 3.46.0 (as of `rusqlite` 0.32.0 / `libsqlite3-sys`
|
||||
0.30.0). This is probably the simplest solution to any build problems. You can enable this by adding the following in your `Cargo.toml` file:
|
||||
```toml
|
||||
[dependencies.rusqlite]
|
||||
version = "0.32.0"
|
||||
features = ["bundled"]
|
||||
```
|
||||
* When using any of the `bundled` features, the build script will honor `SQLITE_MAX_VARIABLE_NUMBER` and `SQLITE_MAX_EXPR_DEPTH` variables. It will also honor a `LIBSQLITE3_FLAGS` variable, which can have a format like `"-USQLITE_ALPHA -DSQLITE_BETA SQLITE_GAMMA ..."`. That would disable the `SQLITE_ALPHA` flag, and set the `SQLITE_BETA` and `SQLITE_GAMMA` flags. (The initial `-D` can be omitted, as on the last one.)
|
||||
* When using `bundled-sqlcipher` (and not also using `bundled-sqlcipher-vendored-openssl`), `libsqlite3-sys` will need to
|
||||
link against crypto libraries on the system. If the build script can find a `libcrypto` from OpenSSL or LibreSSL (it will consult `OPENSSL_LIB_DIR`/`OPENSSL_INCLUDE_DIR` and `OPENSSL_DIR` environment variables), it will use that. If building on and for Macs, and none of those variables are set, it will use the system's SecurityFramework instead.
|
||||
|
||||
* When linking against a SQLite (or SQLCipher) library already on the system (so *not* using any of the `bundled` features), you can set the `SQLITE3_LIB_DIR` (or `SQLCIPHER_LIB_DIR`) environment variable to point to a directory containing the library. You can also set the `SQLITE3_INCLUDE_DIR` (or `SQLCIPHER_INCLUDE_DIR`) variable to point to the directory containing `sqlite3.h`.
|
||||
* Installing the sqlite3 development packages will usually be all that is required, but
|
||||
the build helpers for [pkg-config](https://github.com/alexcrichton/pkg-config-rs)
|
||||
and [vcpkg](https://github.com/mcgoo/vcpkg-rs) have some additional configuration
|
||||
options. The default when using vcpkg is to dynamically link,
|
||||
which must be enabled by setting `VCPKGRS_DYNAMIC=1` environment variable before build.
|
||||
`vcpkg install sqlite3:x64-windows` will install the required library.
|
||||
* When linking against a SQLite (or SQLCipher) library already on the system, you can set the `SQLITE3_STATIC` (or `SQLCIPHER_STATIC`) environment variable to 1 to request that the library be statically instead of dynamically linked.
|
||||
|
||||
|
||||
### Binding generation
|
||||
|
||||
We use [bindgen](https://crates.io/crates/bindgen) to generate the Rust
|
||||
declarations from SQLite's C header file. `bindgen`
|
||||
[recommends](https://github.com/servo/rust-bindgen#library-usage-with-buildrs)
|
||||
running this as part of the build process of libraries that used this. We tried
|
||||
this briefly (`rusqlite` 0.10.0, specifically), but it had some annoyances:
|
||||
|
||||
* The build time for `libsqlite3-sys` (and therefore `rusqlite`) increased
|
||||
dramatically.
|
||||
* Running `bindgen` requires a relatively-recent version of Clang, which many
|
||||
systems do not have installed by default.
|
||||
* Running `bindgen` also requires the SQLite header file to be present.
|
||||
|
||||
As of `rusqlite` 0.10.1, we avoid running `bindgen` at build-time by shipping
|
||||
pregenerated bindings for several versions of SQLite. When compiling
|
||||
`rusqlite`, we use your selected Cargo features to pick the bindings for the
|
||||
minimum SQLite version that supports your chosen features. If you are using
|
||||
`libsqlite3-sys` directly, you can use the same features to choose which
|
||||
pregenerated bindings are chosen:
|
||||
|
||||
* `min_sqlite_version_3_14_0` - SQLite 3.14.0 bindings (this is the default)
|
||||
|
||||
If you use any of the `bundled` features, you will get pregenerated bindings for the
|
||||
bundled version of SQLite/SQLCipher. If you need other specific pregenerated binding
|
||||
versions, please file an issue. If you want to run `bindgen` at buildtime to
|
||||
produce your own bindings, use the `buildtime_bindgen` Cargo feature.
|
||||
|
||||
If you enable the `modern_sqlite` feature, we'll use the bindings we would have
|
||||
included with the bundled build. You generally should have `buildtime_bindgen`
|
||||
enabled if you turn this on, as otherwise you'll need to keep the version of
|
||||
SQLite you link with in sync with what rusqlite would have bundled, (usually the
|
||||
most recent release of SQLite). Failing to do this will cause a runtime error.
|
||||
|
||||
## Contributing
|
||||
|
||||
Rusqlite has many features, and many of them impact the build configuration in
|
||||
incompatible ways. This is unfortunate, and makes testing changes hard.
|
||||
|
||||
To help here: you generally should ensure that you run tests/lint for
|
||||
`--features bundled`, and `--features "bundled-full session buildtime_bindgen"`.
|
||||
|
||||
If running bindgen is problematic for you, `--features bundled-full` enables
|
||||
bundled and all features which don't require binding generation, and can be used
|
||||
instead.
|
||||
|
||||
### Checklist
|
||||
|
||||
- Run `cargo fmt` to ensure your Rust code is correctly formatted.
|
||||
- Ensure `cargo clippy --workspace --features bundled` passes without warnings.
|
||||
- Ensure `cargo clippy --workspace --features "bundled-full session buildtime_bindgen"` passes without warnings.
|
||||
- Ensure `cargo test --workspace --features bundled` reports no failures.
|
||||
- Ensure `cargo test --workspace --features "bundled-full session buildtime_bindgen"` reports no failures.
|
||||
|
||||
## Author
|
||||
|
||||
Rusqlite is the product of hard work by a number of people. A list is available
|
||||
here: https://github.com/rusqlite/rusqlite/graphs/contributors
|
||||
|
||||
## Community
|
||||
|
||||
Feel free to join the [Rusqlite Discord Server](https://discord.gg/nFYfGPB8g4) to discuss or get help with `rusqlite` or `libsqlite3-sys`.
|
||||
|
||||
## License
|
||||
|
||||
Rusqlite and libsqlite3-sys are available under the MIT license. See the LICENSE file for more info.
|
||||
|
||||
### Licenses of Bundled Software
|
||||
|
||||
Depending on the set of enabled cargo `features`, rusqlite and libsqlite3-sys will also bundle other libraries, which have their own licensing terms:
|
||||
|
||||
- If `--features=bundled-sqlcipher` is enabled, the vendored source of [SQLcipher](https://github.com/sqlcipher/sqlcipher) will be compiled and statically linked in. SQLcipher is distributed under a BSD-style license, as described [here](libsqlite3-sys/sqlcipher/LICENSE).
|
||||
|
||||
- If `--features=bundled` is enabled, the vendored source of SQLite will be compiled and linked in. SQLite is in the public domain, as described [here](https://www.sqlite.org/copyright.html).
|
||||
|
||||
Both of these are quite permissive, have no bearing on the license of the code in `rusqlite` or `libsqlite3-sys` themselves, and can be entirely ignored if you do not use the feature in question.
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# `libsqlite3-sys` SQLite Source Override
|
||||
|
||||
This directory is based on the crates.io `libsqlite3-sys` `0.30.1` package.
|
||||
SQLx `0.8.6` requires the `0.30.x` Rust API, so Codex retains that package
|
||||
interface rather than adopting a prerelease SQLx dependency.
|
||||
|
||||
The `sqlite3/` directory is copied verbatim from the upstream `rusqlite`
|
||||
repository at commit
|
||||
[`7bd509863f304a40ba6be1c1e3ad70a221d50490`](https://github.com/rusqlite/rusqlite/commit/7bd509863f304a40ba6be1c1e3ad70a221d50490),
|
||||
which updates the bundled SQLite amalgamation to official SQLite `3.51.3`.
|
||||
SQLite `3.51.3` contains the fix for the WAL-reset corruption bug affecting
|
||||
WAL-mode databases through SQLite `3.51.2`.
|
||||
|
||||
The `codex-state` runtime test `linked_sqlite_has_wal_reset_bug_fix` queries
|
||||
`sqlite_version()` from the actually linked library and rejects vulnerable
|
||||
SQLite releases. Remove this override once a stable SQLx dependency line used
|
||||
by Codex bundles a SQLite release accepted by that guard.
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
# Checks
|
||||
* new [error code(s)](https://sqlite.org/rescode.html)
|
||||
=> Update [libsqlite3-sys/src/error.rs](https://github.com/rusqlite/rusqlite/blob/006c8b77e7d235a3072237f006ebabd66b937911/libsqlite3-sys/src/error.rs#L127)
|
||||
And [code_to_str](https://github.com/rusqlite/rusqlite/blob/006c8b77e7d235a3072237f006ebabd66b937911/libsqlite3-sys/src/error.rs#L195)
|
||||
* new [SQLITE_OPEN_*](https://www.sqlite.org/c3ref/c_open_autoproxy.html)
|
||||
=> Update [struct OpenFlags](https://github.com/rusqlite/rusqlite/blob/19d08871799500d64336f413dc329cc964149f10/src/lib.rs#L999)
|
||||
* new [SQLITE_LIMIT_*](https://sqlite.org/c3ref/c_limit_attached.html)
|
||||
=> Update [enum Limit](https://github.com/rusqlite/rusqlite/blob/66ace52c4a24a811b405ffd9e9010163352a6186/libsqlite3-sys/src/lib.rs#L27)
|
||||
* new [SQLITE_DBCONFIG_*](https://sqlite.org/c3ref/c_dbconfig_defensive.html)
|
||||
=> Update [enum DbConfig](https://github.com/rusqlite/rusqlite/blob/7056e656ac92330a3d78f5ac456dea1e56f6bfee/src/config.rs#L15)
|
||||
* new [Authorizer Action Codes](https://sqlite.org/c3ref/c_alter_table.html)
|
||||
=> Update [enum AuthAction](https://github.com/rusqlite/rusqlite/blob/2ddbebad9763ab8054e55ef509672b7537ba7cf5/src/hooks.rs#L63)
|
||||
* new [SQLITE_STMTSTATUS_*](https://www.sqlite.org/c3ref/c_stmtstatus_counter.html)
|
||||
=> Update [enum StatementStatus](https://github.com/rusqlite/rusqlite/blob/ce90b519bb9946bf1cbab77479bb92d0fbc467c0/src/statement.rs#L937)
|
||||
* new [SQLITE_INDEX_CONSTRAINT_*](https://sqlite.org/c3ref/c_index_constraint_eq.html)
|
||||
=> Update [enum IndexConstraintOp](https://github.com/rusqlite/rusqlite/blob/5d42ba7c29a35dbb8eeb047e84ae0739cb152754/src/vtab/mod.rs#L267)
|
||||
* new [function flag(s)](https://sqlite.org/c3ref/c_deterministic.html)
|
||||
=> Update [struct FunctionFlags](https://github.com/rusqlite/rusqlite/blob/0312937d6a75b45d7e603fa8c6b083bc7774270b/src/functions.rs#L317)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Vendored
-803
@@ -1,803 +0,0 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
/// Tells whether we're building for Windows. This is more suitable than a plain
|
||||
/// `cfg!(windows)`, since the latter does not properly handle cross-compilation
|
||||
///
|
||||
/// Note that there is no way to know at compile-time which system we'll be
|
||||
/// targeting, and this test must be made at run-time (of the build script) See
|
||||
/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
|
||||
fn win_target() -> bool {
|
||||
env::var("CARGO_CFG_WINDOWS").is_ok()
|
||||
}
|
||||
|
||||
/// Tells whether we're building for Android.
|
||||
/// See [`win_target`]
|
||||
#[cfg(any(feature = "bundled", feature = "bundled-windows"))]
|
||||
fn android_target() -> bool {
|
||||
env::var("CARGO_CFG_TARGET_OS").map_or(false, |v| v == "android")
|
||||
}
|
||||
|
||||
/// Tells whether a given compiler will be used `compiler_name` is compared to
|
||||
/// the content of `CARGO_CFG_TARGET_ENV` (and is always lowercase)
|
||||
///
|
||||
/// See [`win_target`]
|
||||
fn is_compiler(compiler_name: &str) -> bool {
|
||||
env::var("CARGO_CFG_TARGET_ENV").map_or(false, |v| v == compiler_name)
|
||||
}
|
||||
|
||||
/// Copy bindgen file from `dir` to `out_path`.
|
||||
fn copy_bindings<T: AsRef<Path>>(dir: &str, bindgen_name: &str, out_path: T) {
|
||||
let from = if cfg!(feature = "loadable_extension") {
|
||||
format!("{dir}/{bindgen_name}_ext.rs")
|
||||
} else {
|
||||
format!("{dir}/{bindgen_name}.rs")
|
||||
};
|
||||
std::fs::copy(from, out_path).expect("Could not copy bindings to output directory");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let out_path = Path::new(&out_dir).join("bindgen.rs");
|
||||
if cfg!(feature = "in_gecko") {
|
||||
// When inside mozilla-central, we are included into the build with
|
||||
// sqlite3.o directly, so we don't want to provide any linker arguments.
|
||||
copy_bindings("sqlite3", "bindgen_bundled_version", out_path);
|
||||
return;
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-env-changed=LIBSQLITE3_SYS_USE_PKG_CONFIG");
|
||||
if env::var_os("LIBSQLITE3_SYS_USE_PKG_CONFIG").map_or(false, |s| s != "0")
|
||||
|| cfg!(feature = "loadable_extension")
|
||||
{
|
||||
build_linked::main(&out_dir, &out_path);
|
||||
} else if cfg!(all(
|
||||
feature = "sqlcipher",
|
||||
not(feature = "bundled-sqlcipher")
|
||||
)) {
|
||||
if cfg!(feature = "bundled") || (win_target() && cfg!(feature = "bundled-windows")) {
|
||||
println!(
|
||||
"cargo:warning=For backwards compatibility, feature 'sqlcipher' overrides
|
||||
features 'bundled' and 'bundled-windows'. If you want a bundled build of
|
||||
SQLCipher (available for the moment only on Unix), use feature 'bundled-sqlcipher'
|
||||
or 'bundled-sqlcipher-vendored-openssl' to also bundle OpenSSL crypto."
|
||||
);
|
||||
}
|
||||
build_linked::main(&out_dir, &out_path);
|
||||
} else if cfg!(feature = "bundled")
|
||||
|| (win_target() && cfg!(feature = "bundled-windows"))
|
||||
|| cfg!(feature = "bundled-sqlcipher")
|
||||
{
|
||||
#[cfg(any(
|
||||
feature = "bundled",
|
||||
feature = "bundled-windows",
|
||||
feature = "bundled-sqlcipher"
|
||||
))]
|
||||
build_bundled::main(&out_dir, &out_path);
|
||||
#[cfg(not(any(
|
||||
feature = "bundled",
|
||||
feature = "bundled-windows",
|
||||
feature = "bundled-sqlcipher"
|
||||
)))]
|
||||
panic!("The runtime test should not run this branch, which has not compiled any logic.")
|
||||
} else {
|
||||
build_linked::main(&out_dir, &out_path);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
feature = "bundled",
|
||||
feature = "bundled-windows",
|
||||
feature = "bundled-sqlcipher"
|
||||
))]
|
||||
mod build_bundled {
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::{is_compiler, win_target};
|
||||
|
||||
pub fn main(out_dir: &str, out_path: &Path) {
|
||||
let lib_name = super::lib_name();
|
||||
|
||||
// This is just a sanity check, the top level `main` should ensure this.
|
||||
assert!(!(cfg!(feature = "bundled-windows") && !cfg!(feature = "bundled") && !win_target()),
|
||||
"This module should not be used: we're not on Windows and the bundled feature has not been enabled");
|
||||
|
||||
#[cfg(feature = "buildtime_bindgen")]
|
||||
{
|
||||
use super::{bindings, HeaderLocation};
|
||||
let header = HeaderLocation::FromPath(lib_name.to_owned());
|
||||
bindings::write_to_out_dir(header, out_path);
|
||||
}
|
||||
#[cfg(not(feature = "buildtime_bindgen"))]
|
||||
{
|
||||
super::copy_bindings(lib_name, "bindgen_bundled_version", out_path);
|
||||
}
|
||||
println!("cargo:include={}/{lib_name}", env!("CARGO_MANIFEST_DIR"));
|
||||
println!("cargo:rerun-if-changed={lib_name}/sqlite3.c");
|
||||
println!("cargo:rerun-if-changed=sqlite3/wasm32-wasi-vfs.c");
|
||||
let mut cfg = cc::Build::new();
|
||||
cfg.file(format!("{lib_name}/sqlite3.c"))
|
||||
.flag("-DSQLITE_CORE")
|
||||
.flag("-DSQLITE_DEFAULT_FOREIGN_KEYS=1")
|
||||
.flag("-DSQLITE_ENABLE_API_ARMOR")
|
||||
.flag("-DSQLITE_ENABLE_COLUMN_METADATA")
|
||||
.flag("-DSQLITE_ENABLE_DBSTAT_VTAB")
|
||||
.flag("-DSQLITE_ENABLE_FTS3")
|
||||
.flag("-DSQLITE_ENABLE_FTS3_PARENTHESIS")
|
||||
.flag("-DSQLITE_ENABLE_FTS5")
|
||||
.flag("-DSQLITE_ENABLE_JSON1")
|
||||
.flag("-DSQLITE_ENABLE_LOAD_EXTENSION=1")
|
||||
.flag("-DSQLITE_ENABLE_MEMORY_MANAGEMENT")
|
||||
.flag("-DSQLITE_ENABLE_RTREE")
|
||||
.flag("-DSQLITE_ENABLE_STAT4")
|
||||
.flag("-DSQLITE_SOUNDEX")
|
||||
.flag("-DSQLITE_THREADSAFE=1")
|
||||
.flag("-DSQLITE_USE_URI")
|
||||
.flag("-DHAVE_USLEEP=1")
|
||||
.flag("-DHAVE_ISNAN")
|
||||
.flag("-D_POSIX_THREAD_SAFE_FUNCTIONS") // cross compile with MinGW
|
||||
.warnings(false);
|
||||
|
||||
if cfg!(feature = "bundled-sqlcipher") {
|
||||
cfg.flag("-DSQLITE_HAS_CODEC").flag("-DSQLITE_TEMP_STORE=2");
|
||||
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let host = env::var("HOST").unwrap();
|
||||
|
||||
let is_windows = host.contains("windows") && target.contains("windows");
|
||||
let is_apple = host.contains("apple") && target.contains("apple");
|
||||
|
||||
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
|
||||
let inc_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
|
||||
let mut use_openssl = false;
|
||||
|
||||
let (lib_dir, inc_dir) = match (lib_dir, inc_dir) {
|
||||
(Some(lib_dir), Some(inc_dir)) => {
|
||||
use_openssl = true;
|
||||
(vec![lib_dir], inc_dir)
|
||||
}
|
||||
(lib_dir, inc_dir) => match find_openssl_dir(&host, &target) {
|
||||
None => {
|
||||
if is_windows && !cfg!(feature = "bundled-sqlcipher-vendored-openssl") {
|
||||
panic!("Missing environment variable OPENSSL_DIR or OPENSSL_DIR is not set")
|
||||
} else {
|
||||
(vec![PathBuf::new()], PathBuf::new())
|
||||
}
|
||||
}
|
||||
Some(openssl_dir) => {
|
||||
let lib_dir = lib_dir.map(|d| vec![d]).unwrap_or_else(|| {
|
||||
let mut lib_dirs = vec![];
|
||||
// OpenSSL 3.0 now puts its libraries in lib64/ by default,
|
||||
// check for both it and lib/.
|
||||
if openssl_dir.join("lib64").exists() {
|
||||
lib_dirs.push(openssl_dir.join("lib64"));
|
||||
}
|
||||
if openssl_dir.join("lib").exists() {
|
||||
lib_dirs.push(openssl_dir.join("lib"));
|
||||
}
|
||||
lib_dirs
|
||||
});
|
||||
let inc_dir = inc_dir.unwrap_or_else(|| openssl_dir.join("include"));
|
||||
|
||||
if !lib_dir.iter().all(|p| p.exists()) {
|
||||
panic!("OpenSSL library directory does not exist: {:?}", lib_dir);
|
||||
}
|
||||
|
||||
if !Path::new(&inc_dir).exists() {
|
||||
panic!(
|
||||
"OpenSSL include directory does not exist: {}",
|
||||
inc_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
||||
use_openssl = true;
|
||||
(lib_dir, inc_dir)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if cfg!(feature = "bundled-sqlcipher-vendored-openssl") {
|
||||
cfg.include(env::var("DEP_OPENSSL_INCLUDE").unwrap());
|
||||
// cargo will resolve downstream to the static lib in
|
||||
// openssl-sys
|
||||
} else if use_openssl {
|
||||
cfg.include(inc_dir.to_string_lossy().as_ref());
|
||||
let lib_name = if is_windows { "libcrypto" } else { "crypto" };
|
||||
println!("cargo:rustc-link-lib=dylib={}", lib_name);
|
||||
for lib_dir_item in lib_dir.iter() {
|
||||
println!("cargo:rustc-link-search={}", lib_dir_item.to_string_lossy());
|
||||
}
|
||||
} else if is_apple {
|
||||
cfg.flag("-DSQLCIPHER_CRYPTO_CC");
|
||||
println!("cargo:rustc-link-lib=framework=Security");
|
||||
println!("cargo:rustc-link-lib=framework=CoreFoundation");
|
||||
} else {
|
||||
// branch not taken on Windows, just `crypto` is fine.
|
||||
println!("cargo:rustc-link-lib=dylib=crypto");
|
||||
}
|
||||
}
|
||||
|
||||
// on android sqlite can't figure out where to put the temp files.
|
||||
// the bundled sqlite on android also uses `SQLITE_TEMP_STORE=3`.
|
||||
// https://android.googlesource.com/platform/external/sqlite/+/2c8c9ae3b7e6f340a19a0001c2a889a211c9d8b2/dist/Android.mk
|
||||
if super::android_target() {
|
||||
cfg.flag("-DSQLITE_TEMP_STORE=3");
|
||||
}
|
||||
|
||||
if cfg!(feature = "with-asan") {
|
||||
cfg.flag("-fsanitize=address");
|
||||
}
|
||||
|
||||
// If explicitly requested: enable static linking against the Microsoft Visual
|
||||
// C++ Runtime to avoid dependencies on vcruntime140.dll and similar libraries.
|
||||
if cfg!(target_feature = "crt-static") && is_compiler("msvc") {
|
||||
cfg.static_crt(true);
|
||||
}
|
||||
|
||||
if !win_target() {
|
||||
cfg.flag("-DHAVE_LOCALTIME_R");
|
||||
}
|
||||
if env::var("TARGET").map_or(false, |v| v == "wasm32-wasi") {
|
||||
cfg.flag("-USQLITE_THREADSAFE")
|
||||
.flag("-DSQLITE_THREADSAFE=0")
|
||||
// https://github.com/rust-lang/rust/issues/74393
|
||||
.flag("-DLONGDOUBLE_TYPE=double")
|
||||
.flag("-D_WASI_EMULATED_MMAN")
|
||||
.flag("-D_WASI_EMULATED_GETPID")
|
||||
.flag("-D_WASI_EMULATED_SIGNAL")
|
||||
.flag("-D_WASI_EMULATED_PROCESS_CLOCKS");
|
||||
|
||||
if cfg!(feature = "wasm32-wasi-vfs") {
|
||||
cfg.file("sqlite3/wasm32-wasi-vfs.c");
|
||||
}
|
||||
}
|
||||
if cfg!(feature = "unlock_notify") {
|
||||
cfg.flag("-DSQLITE_ENABLE_UNLOCK_NOTIFY");
|
||||
}
|
||||
if cfg!(feature = "preupdate_hook") {
|
||||
cfg.flag("-DSQLITE_ENABLE_PREUPDATE_HOOK");
|
||||
}
|
||||
if cfg!(feature = "session") {
|
||||
cfg.flag("-DSQLITE_ENABLE_SESSION");
|
||||
}
|
||||
|
||||
if let Ok(limit) = env::var("SQLITE_MAX_VARIABLE_NUMBER") {
|
||||
cfg.flag(format!("-DSQLITE_MAX_VARIABLE_NUMBER={limit}"));
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed=SQLITE_MAX_VARIABLE_NUMBER");
|
||||
|
||||
if let Ok(limit) = env::var("SQLITE_MAX_EXPR_DEPTH") {
|
||||
cfg.flag(format!("-DSQLITE_MAX_EXPR_DEPTH={limit}"));
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed=SQLITE_MAX_EXPR_DEPTH");
|
||||
|
||||
if let Ok(limit) = env::var("SQLITE_MAX_COLUMN") {
|
||||
cfg.flag(format!("-DSQLITE_MAX_COLUMN={limit}"));
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed=SQLITE_MAX_COLUMN");
|
||||
|
||||
if let Ok(extras) = env::var("LIBSQLITE3_FLAGS") {
|
||||
for extra in extras.split_whitespace() {
|
||||
if extra.starts_with("-D") || extra.starts_with("-U") {
|
||||
cfg.flag(extra);
|
||||
} else if extra.starts_with("SQLITE_") {
|
||||
cfg.flag(format!("-D{extra}"));
|
||||
} else {
|
||||
panic!("Don't understand {} in LIBSQLITE3_FLAGS", extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed=LIBSQLITE3_FLAGS");
|
||||
|
||||
cfg.compile(lib_name);
|
||||
|
||||
println!("cargo:lib_dir={out_dir}");
|
||||
}
|
||||
|
||||
fn env(name: &str) -> Option<OsString> {
|
||||
let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_");
|
||||
let prefixed = format!("{prefix}_{name}");
|
||||
let var = env::var_os(prefixed);
|
||||
|
||||
match var {
|
||||
None => env::var_os(name),
|
||||
_ => var,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_openssl_dir(_host: &str, _target: &str) -> Option<PathBuf> {
|
||||
let openssl_dir = env("OPENSSL_DIR");
|
||||
openssl_dir.map(PathBuf::from)
|
||||
}
|
||||
}
|
||||
|
||||
fn env_prefix() -> &'static str {
|
||||
if cfg!(any(feature = "sqlcipher", feature = "bundled-sqlcipher")) {
|
||||
"SQLCIPHER"
|
||||
} else {
|
||||
"SQLITE3"
|
||||
}
|
||||
}
|
||||
|
||||
fn lib_name() -> &'static str {
|
||||
if cfg!(any(feature = "sqlcipher", feature = "bundled-sqlcipher")) {
|
||||
"sqlcipher"
|
||||
} else {
|
||||
"sqlite3"
|
||||
}
|
||||
}
|
||||
|
||||
pub enum HeaderLocation {
|
||||
FromEnvironment,
|
||||
Wrapper,
|
||||
FromPath(String),
|
||||
}
|
||||
|
||||
impl From<HeaderLocation> for String {
|
||||
fn from(header: HeaderLocation) -> String {
|
||||
match header {
|
||||
HeaderLocation::FromEnvironment => {
|
||||
let prefix = env_prefix();
|
||||
let mut header = env::var(format!("{prefix}_INCLUDE_DIR")).unwrap_or_else(|_| {
|
||||
panic!("{prefix}_INCLUDE_DIR must be set if {prefix}_LIB_DIR is set")
|
||||
});
|
||||
header.push_str(if cfg!(feature = "loadable_extension") {
|
||||
"/sqlite3ext.h"
|
||||
} else {
|
||||
"/sqlite3.h"
|
||||
});
|
||||
header
|
||||
}
|
||||
HeaderLocation::Wrapper => if cfg!(feature = "loadable_extension") {
|
||||
"wrapper_ext.h"
|
||||
} else {
|
||||
"wrapper.h"
|
||||
}
|
||||
.into(),
|
||||
HeaderLocation::FromPath(path) => format!(
|
||||
"{}/{}",
|
||||
path,
|
||||
if cfg!(feature = "loadable_extension") {
|
||||
"sqlite3ext.h"
|
||||
} else {
|
||||
"sqlite3.h"
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod build_linked {
|
||||
#[cfg(feature = "vcpkg")]
|
||||
extern crate vcpkg;
|
||||
|
||||
use super::{bindings, env_prefix, is_compiler, lib_name, win_target, HeaderLocation};
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn main(_out_dir: &str, out_path: &Path) {
|
||||
let header = find_sqlite();
|
||||
if (cfg!(any(
|
||||
feature = "bundled_bindings",
|
||||
feature = "bundled",
|
||||
feature = "bundled-sqlcipher"
|
||||
)) || (win_target() && cfg!(feature = "bundled-windows")))
|
||||
&& !cfg!(feature = "buildtime_bindgen")
|
||||
{
|
||||
// Generally means the `bundled_bindings` feature is enabled.
|
||||
// Most users are better off with turning
|
||||
// on buildtime_bindgen instead, but this is still supported as we
|
||||
// have runtime version checks and there are good reasons to not
|
||||
// want to run bindgen.
|
||||
super::copy_bindings(lib_name(), "bindgen_bundled_version", out_path);
|
||||
} else {
|
||||
bindings::write_to_out_dir(header, out_path);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "loadable_extension"))]
|
||||
fn find_link_mode() -> &'static str {
|
||||
// If the user specifies SQLITE3_STATIC (or SQLCIPHER_STATIC), do static
|
||||
// linking, unless it's explicitly set to 0.
|
||||
match &env::var(format!("{}_STATIC", env_prefix())) {
|
||||
Ok(v) if v != "0" => "static",
|
||||
_ => "dylib",
|
||||
}
|
||||
}
|
||||
// Prints the necessary cargo link commands and returns the path to the header.
|
||||
fn find_sqlite() -> HeaderLocation {
|
||||
let link_lib = lib_name();
|
||||
|
||||
println!("cargo:rerun-if-env-changed={}_INCLUDE_DIR", env_prefix());
|
||||
println!("cargo:rerun-if-env-changed={}_LIB_DIR", env_prefix());
|
||||
println!("cargo:rerun-if-env-changed={}_STATIC", env_prefix());
|
||||
if cfg!(feature = "vcpkg") && is_compiler("msvc") {
|
||||
println!("cargo:rerun-if-env-changed=VCPKGRS_DYNAMIC");
|
||||
}
|
||||
|
||||
// dependents can access `DEP_SQLITE3_LINK_TARGET` (`sqlite3` being the
|
||||
// `links=` value in our Cargo.toml) to get this value. This might be
|
||||
// useful if you need to ensure whatever crypto library sqlcipher relies
|
||||
// on is available, for example.
|
||||
#[cfg(not(feature = "loadable_extension"))]
|
||||
println!("cargo:link-target={link_lib}");
|
||||
|
||||
// Allow users to specify where to find SQLite.
|
||||
if let Ok(dir) = env::var(format!("{}_LIB_DIR", env_prefix())) {
|
||||
// Try to use pkg-config to determine link commands
|
||||
let pkgconfig_path = Path::new(&dir).join("pkgconfig");
|
||||
env::set_var("PKG_CONFIG_PATH", pkgconfig_path);
|
||||
#[cfg(not(feature = "loadable_extension"))]
|
||||
if pkg_config::Config::new().probe(link_lib).is_err() {
|
||||
// Otherwise just emit the bare minimum link commands.
|
||||
println!("cargo:rustc-link-lib={}={link_lib}", find_link_mode());
|
||||
println!("cargo:rustc-link-search={dir}");
|
||||
}
|
||||
return HeaderLocation::FromEnvironment;
|
||||
}
|
||||
|
||||
if let Some(header) = try_vcpkg() {
|
||||
return header;
|
||||
}
|
||||
|
||||
// See if pkg-config can do everything for us.
|
||||
if let Ok(mut lib) = pkg_config::Config::new()
|
||||
.print_system_libs(false)
|
||||
.probe(link_lib)
|
||||
{
|
||||
if let Some(header) = lib.include_paths.pop() {
|
||||
HeaderLocation::FromPath(header.to_string_lossy().into())
|
||||
} else {
|
||||
HeaderLocation::Wrapper
|
||||
}
|
||||
} else {
|
||||
// No env var set and pkg-config couldn't help; just output the link-lib
|
||||
// request and hope that the library exists on the system paths. We used to
|
||||
// output /usr/lib explicitly, but that can introduce other linking problems;
|
||||
// see https://github.com/rusqlite/rusqlite/issues/207.
|
||||
#[cfg(not(feature = "loadable_extension"))]
|
||||
println!("cargo:rustc-link-lib={}={link_lib}", find_link_mode());
|
||||
HeaderLocation::Wrapper
|
||||
}
|
||||
}
|
||||
|
||||
fn try_vcpkg() -> Option<HeaderLocation> {
|
||||
if cfg!(feature = "vcpkg") && is_compiler("msvc") {
|
||||
// See if vcpkg can find it.
|
||||
if let Ok(mut lib) = vcpkg::Config::new().probe(lib_name()) {
|
||||
if let Some(header) = lib.include_paths.pop() {
|
||||
return Some(HeaderLocation::FromPath(header.to_string_lossy().into()));
|
||||
}
|
||||
}
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "buildtime_bindgen"))]
|
||||
#[allow(dead_code)]
|
||||
mod bindings {
|
||||
use super::HeaderLocation;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
static PREBUILT_BINDGENS: &[&str] = &["bindgen_3.14.0"];
|
||||
|
||||
pub fn write_to_out_dir(_header: HeaderLocation, out_path: &Path) {
|
||||
let name = PREBUILT_BINDGENS[PREBUILT_BINDGENS.len() - 1];
|
||||
super::copy_bindings("bindgen-bindings", name, out_path);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "buildtime_bindgen")]
|
||||
mod bindings {
|
||||
use super::HeaderLocation;
|
||||
use bindgen::callbacks::{IntKind, ParseCallbacks};
|
||||
|
||||
use std::path::Path;
|
||||
#[derive(Debug)]
|
||||
struct SqliteTypeChooser;
|
||||
|
||||
impl ParseCallbacks for SqliteTypeChooser {
|
||||
fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
|
||||
if name == "SQLITE_SERIALIZE_NOCOPY"
|
||||
|| name.starts_with("SQLITE_DESERIALIZE_")
|
||||
|| name.starts_with("SQLITE_PREPARE_")
|
||||
{
|
||||
Some(IntKind::UInt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Are we generating the bundled bindings? Used to avoid emitting things
|
||||
// that would be problematic in bundled builds. This env var is set by
|
||||
// `upgrade.sh`.
|
||||
fn generating_bundled_bindings() -> bool {
|
||||
// Hacky way to know if we're generating the bundled bindings
|
||||
println!("cargo:rerun-if-env-changed=LIBSQLITE3_SYS_BUNDLING");
|
||||
match std::env::var("LIBSQLITE3_SYS_BUNDLING") {
|
||||
Ok(v) => v != "0",
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_to_out_dir(header: HeaderLocation, out_path: &Path) {
|
||||
let header: String = header.into();
|
||||
let mut bindings = bindgen::builder()
|
||||
.default_macro_constant_type(bindgen::MacroTypeVariation::Signed)
|
||||
.disable_nested_struct_naming()
|
||||
.trust_clang_mangling(false)
|
||||
.header(header.clone())
|
||||
.parse_callbacks(Box::new(SqliteTypeChooser));
|
||||
if cfg!(feature = "loadable_extension") {
|
||||
bindings = bindings.ignore_functions(); // see generate_functions
|
||||
} else {
|
||||
bindings = bindings
|
||||
.blocklist_function("sqlite3_auto_extension")
|
||||
.raw_line(
|
||||
r#"extern "C" {
|
||||
pub fn sqlite3_auto_extension(
|
||||
xEntryPoint: ::std::option::Option<
|
||||
unsafe extern "C" fn(
|
||||
db: *mut sqlite3,
|
||||
pzErrMsg: *mut *mut ::std::os::raw::c_char,
|
||||
_: *const sqlite3_api_routines,
|
||||
) -> ::std::os::raw::c_int,
|
||||
>,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}"#,
|
||||
)
|
||||
.blocklist_function("sqlite3_cancel_auto_extension")
|
||||
.raw_line(
|
||||
r#"extern "C" {
|
||||
pub fn sqlite3_cancel_auto_extension(
|
||||
xEntryPoint: ::std::option::Option<
|
||||
unsafe extern "C" fn(
|
||||
db: *mut sqlite3,
|
||||
pzErrMsg: *mut *mut ::std::os::raw::c_char,
|
||||
_: *const sqlite3_api_routines,
|
||||
) -> ::std::os::raw::c_int,
|
||||
>,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}"#,
|
||||
)
|
||||
.blocklist_function(".*16.*")
|
||||
.blocklist_function("sqlite3_close_v2")
|
||||
.blocklist_function("sqlite3_create_collation")
|
||||
.blocklist_function("sqlite3_create_function")
|
||||
.blocklist_function("sqlite3_create_module")
|
||||
.blocklist_function("sqlite3_prepare");
|
||||
}
|
||||
|
||||
if cfg!(any(feature = "sqlcipher", feature = "bundled-sqlcipher")) {
|
||||
bindings = bindings.clang_arg("-DSQLITE_HAS_CODEC");
|
||||
}
|
||||
if cfg!(feature = "unlock_notify") {
|
||||
bindings = bindings.clang_arg("-DSQLITE_ENABLE_UNLOCK_NOTIFY");
|
||||
}
|
||||
if cfg!(feature = "preupdate_hook") {
|
||||
bindings = bindings.clang_arg("-DSQLITE_ENABLE_PREUPDATE_HOOK");
|
||||
}
|
||||
if cfg!(feature = "session") {
|
||||
bindings = bindings.clang_arg("-DSQLITE_ENABLE_SESSION");
|
||||
}
|
||||
|
||||
// When cross compiling unless effort is taken to fix the issue, bindgen
|
||||
// will find the wrong headers. There's only one header included by the
|
||||
// amalgamated `sqlite.h`: `stdarg.h`.
|
||||
//
|
||||
// Thankfully, there's almost no case where rust code needs to use
|
||||
// functions taking `va_list` (It's nearly impossible to get a `va_list`
|
||||
// in Rust unless you get passed it by C code for some reason).
|
||||
//
|
||||
// Arguably, we should never be including these, but we include them for
|
||||
// the cases where they aren't totally broken...
|
||||
let target_arch = std::env::var("TARGET").unwrap();
|
||||
let host_arch = std::env::var("HOST").unwrap();
|
||||
let is_cross_compiling = target_arch != host_arch;
|
||||
|
||||
// Note that when generating the bundled file, we're essentially always
|
||||
// cross compiling.
|
||||
if generating_bundled_bindings() || is_cross_compiling {
|
||||
// Get rid of va_list, as it's not
|
||||
bindings = bindings
|
||||
.blocklist_function("sqlite3_vmprintf")
|
||||
.blocklist_function("sqlite3_vsnprintf")
|
||||
.blocklist_function("sqlite3_str_vappendf")
|
||||
.blocklist_type("va_list")
|
||||
.blocklist_item("__.*");
|
||||
}
|
||||
|
||||
let bindings = bindings
|
||||
.layout_tests(false)
|
||||
.generate()
|
||||
.unwrap_or_else(|_| panic!("could not run bindgen on header {}", header));
|
||||
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
{
|
||||
let mut output = Vec::new();
|
||||
bindings
|
||||
.write(Box::new(&mut output))
|
||||
.expect("could not write output of bindgen");
|
||||
let mut output = String::from_utf8(output).expect("bindgen output was not UTF-8?!");
|
||||
super::loadable_extension::generate_functions(&mut output);
|
||||
std::fs::write(out_path, output.as_bytes())
|
||||
.unwrap_or_else(|_| panic!("Could not write to {:?}", out_path));
|
||||
}
|
||||
#[cfg(not(feature = "loadable_extension"))]
|
||||
bindings
|
||||
.write_to_file(out_path)
|
||||
.unwrap_or_else(|_| panic!("Could not write to {:?}", out_path));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "buildtime_bindgen", feature = "loadable_extension"))]
|
||||
mod loadable_extension {
|
||||
/// try to generate similar rust code for all `#define sqlite3_xyz
|
||||
/// sqlite3_api->abc` macros` in sqlite3ext.h
|
||||
pub fn generate_functions(output: &mut String) {
|
||||
// (1) parse sqlite3_api_routines fields from bindgen output
|
||||
let ast: syn::File = syn::parse_str(output).expect("could not parse bindgen output");
|
||||
let sqlite3_api_routines: syn::ItemStruct = ast
|
||||
.items
|
||||
.into_iter()
|
||||
.find_map(|i| {
|
||||
if let syn::Item::Struct(s) = i {
|
||||
if s.ident == "sqlite3_api_routines" {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.expect("could not find sqlite3_api_routines");
|
||||
let sqlite3_api_routines_ident = sqlite3_api_routines.ident;
|
||||
let p_api = quote::format_ident!("p_api");
|
||||
let mut stores = Vec::new();
|
||||
let mut malloc = Vec::new();
|
||||
// (2) `#define sqlite3_xyz sqlite3_api->abc` => `pub unsafe fn
|
||||
// sqlite3_xyz(args) -> ty {...}` for each `abc` field:
|
||||
for field in sqlite3_api_routines.fields {
|
||||
let ident = field.ident.expect("unnamed field");
|
||||
let span = ident.span();
|
||||
let name = ident.to_string();
|
||||
if name.contains("16") {
|
||||
continue; // skip UTF-16 api as rust uses UTF-8
|
||||
} else if name == "vmprintf" || name == "xvsnprintf" || name == "str_vappendf" {
|
||||
continue; // skip va_list
|
||||
} else if name == "aggregate_count"
|
||||
|| name == "expired"
|
||||
|| name == "global_recover"
|
||||
|| name == "thread_cleanup"
|
||||
|| name == "transfer_bindings"
|
||||
|| name == "create_collation"
|
||||
|| name == "create_function"
|
||||
|| name == "create_module"
|
||||
|| name == "prepare"
|
||||
|| name == "close_v2"
|
||||
{
|
||||
continue; // omit deprecated
|
||||
}
|
||||
let sqlite3_name = match name.as_ref() {
|
||||
"xthreadsafe" => "sqlite3_threadsafe".to_owned(),
|
||||
"interruptx" => "sqlite3_interrupt".to_owned(),
|
||||
_ => {
|
||||
format!("sqlite3_{name}")
|
||||
}
|
||||
};
|
||||
let ptr_name =
|
||||
syn::Ident::new(format!("__{}", sqlite3_name.to_uppercase()).as_ref(), span);
|
||||
let sqlite3_fn_name = syn::Ident::new(&sqlite3_name, span);
|
||||
let method =
|
||||
extract_method(&field.ty).unwrap_or_else(|| panic!("unexpected type for {name}"));
|
||||
let arg_names: syn::punctuated::Punctuated<&syn::Ident, syn::token::Comma> = method
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|i| &i.name.as_ref().unwrap().0)
|
||||
.collect();
|
||||
let args = &method.inputs;
|
||||
// vtab_config/sqlite3_vtab_config: ok
|
||||
let varargs = &method.variadic;
|
||||
if varargs.is_some() && "db_config" != name && "log" != name && "vtab_config" != name {
|
||||
continue; // skip ...
|
||||
}
|
||||
let ty = &method.output;
|
||||
let tokens = if "db_config" == name {
|
||||
quote::quote! {
|
||||
static #ptr_name: ::std::sync::atomic::AtomicPtr<()> = ::std::sync::atomic::AtomicPtr::new(::std::ptr::null_mut());
|
||||
pub unsafe fn #sqlite3_fn_name(#args arg3: ::std::os::raw::c_int, arg4: *mut ::std::os::raw::c_int) #ty {
|
||||
let ptr = #ptr_name.load(::std::sync::atomic::Ordering::Acquire);
|
||||
assert!(!ptr.is_null(), "SQLite API not initialized");
|
||||
let fun: unsafe extern "C" fn(#args #varargs) #ty = ::std::mem::transmute(ptr);
|
||||
(fun)(#arg_names, arg3, arg4)
|
||||
}
|
||||
}
|
||||
} else if "log" == name {
|
||||
quote::quote! {
|
||||
static #ptr_name: ::std::sync::atomic::AtomicPtr<()> = ::std::sync::atomic::AtomicPtr::new(::std::ptr::null_mut());
|
||||
pub unsafe fn #sqlite3_fn_name(#args arg3: *const ::std::os::raw::c_char) #ty {
|
||||
let ptr = #ptr_name.load(::std::sync::atomic::Ordering::Acquire);
|
||||
assert!(!ptr.is_null(), "SQLite API not initialized");
|
||||
let fun: unsafe extern "C" fn(#args #varargs) #ty = ::std::mem::transmute(ptr);
|
||||
(fun)(#arg_names, arg3)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote::quote! {
|
||||
static #ptr_name: ::std::sync::atomic::AtomicPtr<()> = ::std::sync::atomic::AtomicPtr::new(::std::ptr::null_mut());
|
||||
pub unsafe fn #sqlite3_fn_name(#args) #ty {
|
||||
let ptr = #ptr_name.load(::std::sync::atomic::Ordering::Acquire);
|
||||
assert!(!ptr.is_null(), "SQLite API not initialized or SQLite feature omitted");
|
||||
let fun: unsafe extern "C" fn(#args #varargs) #ty = ::std::mem::transmute(ptr);
|
||||
(fun)(#arg_names)
|
||||
}
|
||||
}
|
||||
};
|
||||
output.push_str(&prettyplease::unparse(
|
||||
&syn::parse2(tokens).expect("could not parse quote output"),
|
||||
));
|
||||
output.push('\n');
|
||||
if name == "malloc" {
|
||||
&mut malloc
|
||||
} else {
|
||||
&mut stores
|
||||
}
|
||||
.push(quote::quote! {
|
||||
if let Some(fun) = (*#p_api).#ident {
|
||||
#ptr_name.store(
|
||||
fun as usize as *mut (),
|
||||
::std::sync::atomic::Ordering::Release,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
// (3) generate rust code similar to SQLITE_EXTENSION_INIT2 macro
|
||||
let tokens = quote::quote! {
|
||||
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||
pub unsafe fn rusqlite_extension_init2(#p_api: *mut #sqlite3_api_routines_ident) -> ::std::result::Result<(),crate::InitError> {
|
||||
#(#malloc)* // sqlite3_malloc needed by to_sqlite_error
|
||||
if let Some(fun) = (*#p_api).libversion_number {
|
||||
let version = fun();
|
||||
if SQLITE_VERSION_NUMBER > version {
|
||||
return Err(crate::InitError::VersionMismatch{compile_time: SQLITE_VERSION_NUMBER, runtime: version});
|
||||
}
|
||||
} else {
|
||||
return Err(crate::InitError::NullFunctionPointer);
|
||||
}
|
||||
#(#stores)*
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
output.push_str(&prettyplease::unparse(
|
||||
&syn::parse2(tokens).expect("could not parse quote output"),
|
||||
));
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
fn extract_method(ty: &syn::Type) -> Option<&syn::TypeBareFn> {
|
||||
match ty {
|
||||
syn::Type::Path(tp) => tp.path.segments.last(),
|
||||
_ => None,
|
||||
}
|
||||
.map(|seg| match &seg.arguments {
|
||||
syn::PathArguments::AngleBracketed(args) => args.args.first(),
|
||||
_ => None,
|
||||
})?
|
||||
.map(|arg| match arg {
|
||||
syn::GenericArgument::Type(t) => Some(t),
|
||||
_ => None,
|
||||
})?
|
||||
.map(|ty| match ty {
|
||||
syn::Type::BareFn(r) => Some(r),
|
||||
_ => None,
|
||||
})?
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
Copyright (c) 2008-2020 Zetetic LLC
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the ZETETIC LLC nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
-261439
File diff suppressed because it is too large
Load Diff
-13434
File diff suppressed because it is too large
Load Diff
-719
@@ -1,719 +0,0 @@
|
||||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
/* Version 3.7.16 and later */
|
||||
int (*close_v2)(sqlite3*);
|
||||
const char *(*db_filename)(sqlite3*,const char*);
|
||||
int (*db_readonly)(sqlite3*,const char*);
|
||||
int (*db_release_memory)(sqlite3*);
|
||||
const char *(*errstr)(int);
|
||||
int (*stmt_busy)(sqlite3_stmt*);
|
||||
int (*stmt_readonly)(sqlite3_stmt*);
|
||||
int (*stricmp)(const char*,const char*);
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
/* Version 3.38.0 and later */
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
/* Version 3.39.0 and later */
|
||||
int (*deserialize)(sqlite3*,const char*,unsigned char*,
|
||||
sqlite3_int64,sqlite3_int64,unsigned);
|
||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||
unsigned int);
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
/* Version 3.44.0 and later */
|
||||
void *(*get_clientdata)(sqlite3*,const char*);
|
||||
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
#endif
|
||||
#define sqlite3_bind_blob sqlite3_api->bind_blob
|
||||
#define sqlite3_bind_double sqlite3_api->bind_double
|
||||
#define sqlite3_bind_int sqlite3_api->bind_int
|
||||
#define sqlite3_bind_int64 sqlite3_api->bind_int64
|
||||
#define sqlite3_bind_null sqlite3_api->bind_null
|
||||
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
|
||||
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
|
||||
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
|
||||
#define sqlite3_bind_text sqlite3_api->bind_text
|
||||
#define sqlite3_bind_text16 sqlite3_api->bind_text16
|
||||
#define sqlite3_bind_value sqlite3_api->bind_value
|
||||
#define sqlite3_busy_handler sqlite3_api->busy_handler
|
||||
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
|
||||
#define sqlite3_changes sqlite3_api->changes
|
||||
#define sqlite3_close sqlite3_api->close
|
||||
#define sqlite3_collation_needed sqlite3_api->collation_needed
|
||||
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
|
||||
#define sqlite3_column_blob sqlite3_api->column_blob
|
||||
#define sqlite3_column_bytes sqlite3_api->column_bytes
|
||||
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
|
||||
#define sqlite3_column_count sqlite3_api->column_count
|
||||
#define sqlite3_column_database_name sqlite3_api->column_database_name
|
||||
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
|
||||
#define sqlite3_column_decltype sqlite3_api->column_decltype
|
||||
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
|
||||
#define sqlite3_column_double sqlite3_api->column_double
|
||||
#define sqlite3_column_int sqlite3_api->column_int
|
||||
#define sqlite3_column_int64 sqlite3_api->column_int64
|
||||
#define sqlite3_column_name sqlite3_api->column_name
|
||||
#define sqlite3_column_name16 sqlite3_api->column_name16
|
||||
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
|
||||
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
|
||||
#define sqlite3_column_table_name sqlite3_api->column_table_name
|
||||
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
|
||||
#define sqlite3_column_text sqlite3_api->column_text
|
||||
#define sqlite3_column_text16 sqlite3_api->column_text16
|
||||
#define sqlite3_column_type sqlite3_api->column_type
|
||||
#define sqlite3_column_value sqlite3_api->column_value
|
||||
#define sqlite3_commit_hook sqlite3_api->commit_hook
|
||||
#define sqlite3_complete sqlite3_api->complete
|
||||
#define sqlite3_complete16 sqlite3_api->complete16
|
||||
#define sqlite3_create_collation sqlite3_api->create_collation
|
||||
#define sqlite3_create_collation16 sqlite3_api->create_collation16
|
||||
#define sqlite3_create_function sqlite3_api->create_function
|
||||
#define sqlite3_create_function16 sqlite3_api->create_function16
|
||||
#define sqlite3_create_module sqlite3_api->create_module
|
||||
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
|
||||
#define sqlite3_data_count sqlite3_api->data_count
|
||||
#define sqlite3_db_handle sqlite3_api->db_handle
|
||||
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
|
||||
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
|
||||
#define sqlite3_errcode sqlite3_api->errcode
|
||||
#define sqlite3_errmsg sqlite3_api->errmsg
|
||||
#define sqlite3_errmsg16 sqlite3_api->errmsg16
|
||||
#define sqlite3_exec sqlite3_api->exec
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_expired sqlite3_api->expired
|
||||
#endif
|
||||
#define sqlite3_finalize sqlite3_api->finalize
|
||||
#define sqlite3_free sqlite3_api->free
|
||||
#define sqlite3_free_table sqlite3_api->free_table
|
||||
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
|
||||
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
|
||||
#define sqlite3_get_table sqlite3_api->get_table
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_global_recover sqlite3_api->global_recover
|
||||
#endif
|
||||
#define sqlite3_interrupt sqlite3_api->interruptx
|
||||
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
|
||||
#define sqlite3_libversion sqlite3_api->libversion
|
||||
#define sqlite3_libversion_number sqlite3_api->libversion_number
|
||||
#define sqlite3_malloc sqlite3_api->malloc
|
||||
#define sqlite3_mprintf sqlite3_api->mprintf
|
||||
#define sqlite3_open sqlite3_api->open
|
||||
#define sqlite3_open16 sqlite3_api->open16
|
||||
#define sqlite3_prepare sqlite3_api->prepare
|
||||
#define sqlite3_prepare16 sqlite3_api->prepare16
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_profile sqlite3_api->profile
|
||||
#define sqlite3_progress_handler sqlite3_api->progress_handler
|
||||
#define sqlite3_realloc sqlite3_api->realloc
|
||||
#define sqlite3_reset sqlite3_api->reset
|
||||
#define sqlite3_result_blob sqlite3_api->result_blob
|
||||
#define sqlite3_result_double sqlite3_api->result_double
|
||||
#define sqlite3_result_error sqlite3_api->result_error
|
||||
#define sqlite3_result_error16 sqlite3_api->result_error16
|
||||
#define sqlite3_result_int sqlite3_api->result_int
|
||||
#define sqlite3_result_int64 sqlite3_api->result_int64
|
||||
#define sqlite3_result_null sqlite3_api->result_null
|
||||
#define sqlite3_result_text sqlite3_api->result_text
|
||||
#define sqlite3_result_text16 sqlite3_api->result_text16
|
||||
#define sqlite3_result_text16be sqlite3_api->result_text16be
|
||||
#define sqlite3_result_text16le sqlite3_api->result_text16le
|
||||
#define sqlite3_result_value sqlite3_api->result_value
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
#define sqlite3_total_changes sqlite3_api->total_changes
|
||||
#define sqlite3_trace sqlite3_api->trace
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
|
||||
#endif
|
||||
#define sqlite3_update_hook sqlite3_api->update_hook
|
||||
#define sqlite3_user_data sqlite3_api->user_data
|
||||
#define sqlite3_value_blob sqlite3_api->value_blob
|
||||
#define sqlite3_value_bytes sqlite3_api->value_bytes
|
||||
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
|
||||
#define sqlite3_value_double sqlite3_api->value_double
|
||||
#define sqlite3_value_int sqlite3_api->value_int
|
||||
#define sqlite3_value_int64 sqlite3_api->value_int64
|
||||
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
|
||||
#define sqlite3_value_text sqlite3_api->value_text
|
||||
#define sqlite3_value_text16 sqlite3_api->value_text16
|
||||
#define sqlite3_value_text16be sqlite3_api->value_text16be
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
|
||||
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
|
||||
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
|
||||
#define sqlite3_blob_close sqlite3_api->blob_close
|
||||
#define sqlite3_blob_open sqlite3_api->blob_open
|
||||
#define sqlite3_blob_read sqlite3_api->blob_read
|
||||
#define sqlite3_blob_write sqlite3_api->blob_write
|
||||
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
|
||||
#define sqlite3_file_control sqlite3_api->file_control
|
||||
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
|
||||
#define sqlite3_memory_used sqlite3_api->memory_used
|
||||
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
|
||||
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
|
||||
#define sqlite3_mutex_free sqlite3_api->mutex_free
|
||||
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
|
||||
#define sqlite3_mutex_try sqlite3_api->mutex_try
|
||||
#define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
#define sqlite3_release_memory sqlite3_api->release_memory
|
||||
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
|
||||
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
|
||||
#define sqlite3_sleep sqlite3_api->sleep
|
||||
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
|
||||
#define sqlite3_vfs_find sqlite3_api->vfs_find
|
||||
#define sqlite3_vfs_register sqlite3_api->vfs_register
|
||||
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
|
||||
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
|
||||
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
|
||||
#define sqlite3_result_error_code sqlite3_api->result_error_code
|
||||
#define sqlite3_test_control sqlite3_api->test_control
|
||||
#define sqlite3_randomness sqlite3_api->randomness
|
||||
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
|
||||
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
|
||||
#define sqlite3_limit sqlite3_api->limit
|
||||
#define sqlite3_next_stmt sqlite3_api->next_stmt
|
||||
#define sqlite3_sql sqlite3_api->sql
|
||||
#define sqlite3_status sqlite3_api->status
|
||||
#define sqlite3_backup_finish sqlite3_api->backup_finish
|
||||
#define sqlite3_backup_init sqlite3_api->backup_init
|
||||
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
|
||||
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
|
||||
#define sqlite3_backup_step sqlite3_api->backup_step
|
||||
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
|
||||
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
|
||||
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
|
||||
#define sqlite3_db_config sqlite3_api->db_config
|
||||
#define sqlite3_db_mutex sqlite3_api->db_mutex
|
||||
#define sqlite3_db_status sqlite3_api->db_status
|
||||
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
|
||||
#define sqlite3_log sqlite3_api->log
|
||||
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
|
||||
#define sqlite3_sourceid sqlite3_api->sourceid
|
||||
#define sqlite3_stmt_status sqlite3_api->stmt_status
|
||||
#define sqlite3_strnicmp sqlite3_api->strnicmp
|
||||
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
|
||||
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
|
||||
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
|
||||
#define sqlite3_wal_hook sqlite3_api->wal_hook
|
||||
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
|
||||
#define sqlite3_vtab_config sqlite3_api->vtab_config
|
||||
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
|
||||
/* Version 3.7.16 and later */
|
||||
#define sqlite3_close_v2 sqlite3_api->close_v2
|
||||
#define sqlite3_db_filename sqlite3_api->db_filename
|
||||
#define sqlite3_db_readonly sqlite3_api->db_readonly
|
||||
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
|
||||
#define sqlite3_errstr sqlite3_api->errstr
|
||||
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
|
||||
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
|
||||
#define sqlite3_stricmp sqlite3_api->stricmp
|
||||
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
|
||||
#define sqlite3_uri_int64 sqlite3_api->uri_int64
|
||||
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
|
||||
/* Version 3.8.7 and later */
|
||||
#define sqlite3_auto_extension sqlite3_api->auto_extension
|
||||
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
|
||||
#define sqlite3_bind_text64 sqlite3_api->bind_text64
|
||||
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
|
||||
#define sqlite3_load_extension sqlite3_api->load_extension
|
||||
#define sqlite3_malloc64 sqlite3_api->malloc64
|
||||
#define sqlite3_msize sqlite3_api->msize
|
||||
#define sqlite3_realloc64 sqlite3_api->realloc64
|
||||
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
|
||||
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
|
||||
/* Version 3.9.0 and later */
|
||||
#define sqlite3_value_subtype sqlite3_api->value_subtype
|
||||
#define sqlite3_result_subtype sqlite3_api->result_subtype
|
||||
/* Version 3.10.0 and later */
|
||||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
/* Version 3.20.0 and later */
|
||||
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
|
||||
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
|
||||
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
|
||||
#define sqlite3_result_pointer sqlite3_api->result_pointer
|
||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||
/* Version 3.22.0 and later */
|
||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
||||
/* Version 3.24.0 and later */
|
||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
||||
#define sqlite3_str_new sqlite3_api->str_new
|
||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
||||
#define sqlite3_str_append sqlite3_api->str_append
|
||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
/* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
/* Version 3.38.0 and later */
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#define sqlite3_deserialize sqlite3_api->deserialize
|
||||
#define sqlite3_serialize sqlite3_api->serialize
|
||||
#endif
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
/* Version 3.44.0 and later */
|
||||
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
|
||||
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE3EXT_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-265977
File diff suppressed because it is too large
Load Diff
-13968
File diff suppressed because it is too large
Load Diff
-730
@@ -1,730 +0,0 @@
|
||||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
/* Version 3.7.16 and later */
|
||||
int (*close_v2)(sqlite3*);
|
||||
const char *(*db_filename)(sqlite3*,const char*);
|
||||
int (*db_readonly)(sqlite3*,const char*);
|
||||
int (*db_release_memory)(sqlite3*);
|
||||
const char *(*errstr)(int);
|
||||
int (*stmt_busy)(sqlite3_stmt*);
|
||||
int (*stmt_readonly)(sqlite3_stmt*);
|
||||
int (*stricmp)(const char*,const char*);
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
/* Version 3.38.0 and later */
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
/* Version 3.39.0 and later */
|
||||
int (*deserialize)(sqlite3*,const char*,unsigned char*,
|
||||
sqlite3_int64,sqlite3_int64,unsigned);
|
||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||
unsigned int);
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
/* Version 3.44.0 and later */
|
||||
void *(*get_clientdata)(sqlite3*,const char*);
|
||||
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
|
||||
/* Version 3.50.0 and later */
|
||||
int (*setlk_timeout)(sqlite3*,int,int);
|
||||
/* Version 3.51.0 and later */
|
||||
int (*set_errmsg)(sqlite3*,int,const char*);
|
||||
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
#endif
|
||||
#define sqlite3_bind_blob sqlite3_api->bind_blob
|
||||
#define sqlite3_bind_double sqlite3_api->bind_double
|
||||
#define sqlite3_bind_int sqlite3_api->bind_int
|
||||
#define sqlite3_bind_int64 sqlite3_api->bind_int64
|
||||
#define sqlite3_bind_null sqlite3_api->bind_null
|
||||
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
|
||||
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
|
||||
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
|
||||
#define sqlite3_bind_text sqlite3_api->bind_text
|
||||
#define sqlite3_bind_text16 sqlite3_api->bind_text16
|
||||
#define sqlite3_bind_value sqlite3_api->bind_value
|
||||
#define sqlite3_busy_handler sqlite3_api->busy_handler
|
||||
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
|
||||
#define sqlite3_changes sqlite3_api->changes
|
||||
#define sqlite3_close sqlite3_api->close
|
||||
#define sqlite3_collation_needed sqlite3_api->collation_needed
|
||||
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
|
||||
#define sqlite3_column_blob sqlite3_api->column_blob
|
||||
#define sqlite3_column_bytes sqlite3_api->column_bytes
|
||||
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
|
||||
#define sqlite3_column_count sqlite3_api->column_count
|
||||
#define sqlite3_column_database_name sqlite3_api->column_database_name
|
||||
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
|
||||
#define sqlite3_column_decltype sqlite3_api->column_decltype
|
||||
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
|
||||
#define sqlite3_column_double sqlite3_api->column_double
|
||||
#define sqlite3_column_int sqlite3_api->column_int
|
||||
#define sqlite3_column_int64 sqlite3_api->column_int64
|
||||
#define sqlite3_column_name sqlite3_api->column_name
|
||||
#define sqlite3_column_name16 sqlite3_api->column_name16
|
||||
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
|
||||
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
|
||||
#define sqlite3_column_table_name sqlite3_api->column_table_name
|
||||
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
|
||||
#define sqlite3_column_text sqlite3_api->column_text
|
||||
#define sqlite3_column_text16 sqlite3_api->column_text16
|
||||
#define sqlite3_column_type sqlite3_api->column_type
|
||||
#define sqlite3_column_value sqlite3_api->column_value
|
||||
#define sqlite3_commit_hook sqlite3_api->commit_hook
|
||||
#define sqlite3_complete sqlite3_api->complete
|
||||
#define sqlite3_complete16 sqlite3_api->complete16
|
||||
#define sqlite3_create_collation sqlite3_api->create_collation
|
||||
#define sqlite3_create_collation16 sqlite3_api->create_collation16
|
||||
#define sqlite3_create_function sqlite3_api->create_function
|
||||
#define sqlite3_create_function16 sqlite3_api->create_function16
|
||||
#define sqlite3_create_module sqlite3_api->create_module
|
||||
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
|
||||
#define sqlite3_data_count sqlite3_api->data_count
|
||||
#define sqlite3_db_handle sqlite3_api->db_handle
|
||||
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
|
||||
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
|
||||
#define sqlite3_errcode sqlite3_api->errcode
|
||||
#define sqlite3_errmsg sqlite3_api->errmsg
|
||||
#define sqlite3_errmsg16 sqlite3_api->errmsg16
|
||||
#define sqlite3_exec sqlite3_api->exec
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_expired sqlite3_api->expired
|
||||
#endif
|
||||
#define sqlite3_finalize sqlite3_api->finalize
|
||||
#define sqlite3_free sqlite3_api->free
|
||||
#define sqlite3_free_table sqlite3_api->free_table
|
||||
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
|
||||
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
|
||||
#define sqlite3_get_table sqlite3_api->get_table
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_global_recover sqlite3_api->global_recover
|
||||
#endif
|
||||
#define sqlite3_interrupt sqlite3_api->interruptx
|
||||
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
|
||||
#define sqlite3_libversion sqlite3_api->libversion
|
||||
#define sqlite3_libversion_number sqlite3_api->libversion_number
|
||||
#define sqlite3_malloc sqlite3_api->malloc
|
||||
#define sqlite3_mprintf sqlite3_api->mprintf
|
||||
#define sqlite3_open sqlite3_api->open
|
||||
#define sqlite3_open16 sqlite3_api->open16
|
||||
#define sqlite3_prepare sqlite3_api->prepare
|
||||
#define sqlite3_prepare16 sqlite3_api->prepare16
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_profile sqlite3_api->profile
|
||||
#define sqlite3_progress_handler sqlite3_api->progress_handler
|
||||
#define sqlite3_realloc sqlite3_api->realloc
|
||||
#define sqlite3_reset sqlite3_api->reset
|
||||
#define sqlite3_result_blob sqlite3_api->result_blob
|
||||
#define sqlite3_result_double sqlite3_api->result_double
|
||||
#define sqlite3_result_error sqlite3_api->result_error
|
||||
#define sqlite3_result_error16 sqlite3_api->result_error16
|
||||
#define sqlite3_result_int sqlite3_api->result_int
|
||||
#define sqlite3_result_int64 sqlite3_api->result_int64
|
||||
#define sqlite3_result_null sqlite3_api->result_null
|
||||
#define sqlite3_result_text sqlite3_api->result_text
|
||||
#define sqlite3_result_text16 sqlite3_api->result_text16
|
||||
#define sqlite3_result_text16be sqlite3_api->result_text16be
|
||||
#define sqlite3_result_text16le sqlite3_api->result_text16le
|
||||
#define sqlite3_result_value sqlite3_api->result_value
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
#define sqlite3_total_changes sqlite3_api->total_changes
|
||||
#define sqlite3_trace sqlite3_api->trace
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
|
||||
#endif
|
||||
#define sqlite3_update_hook sqlite3_api->update_hook
|
||||
#define sqlite3_user_data sqlite3_api->user_data
|
||||
#define sqlite3_value_blob sqlite3_api->value_blob
|
||||
#define sqlite3_value_bytes sqlite3_api->value_bytes
|
||||
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
|
||||
#define sqlite3_value_double sqlite3_api->value_double
|
||||
#define sqlite3_value_int sqlite3_api->value_int
|
||||
#define sqlite3_value_int64 sqlite3_api->value_int64
|
||||
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
|
||||
#define sqlite3_value_text sqlite3_api->value_text
|
||||
#define sqlite3_value_text16 sqlite3_api->value_text16
|
||||
#define sqlite3_value_text16be sqlite3_api->value_text16be
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
|
||||
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
|
||||
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
|
||||
#define sqlite3_blob_close sqlite3_api->blob_close
|
||||
#define sqlite3_blob_open sqlite3_api->blob_open
|
||||
#define sqlite3_blob_read sqlite3_api->blob_read
|
||||
#define sqlite3_blob_write sqlite3_api->blob_write
|
||||
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
|
||||
#define sqlite3_file_control sqlite3_api->file_control
|
||||
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
|
||||
#define sqlite3_memory_used sqlite3_api->memory_used
|
||||
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
|
||||
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
|
||||
#define sqlite3_mutex_free sqlite3_api->mutex_free
|
||||
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
|
||||
#define sqlite3_mutex_try sqlite3_api->mutex_try
|
||||
#define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
#define sqlite3_release_memory sqlite3_api->release_memory
|
||||
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
|
||||
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
|
||||
#define sqlite3_sleep sqlite3_api->sleep
|
||||
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
|
||||
#define sqlite3_vfs_find sqlite3_api->vfs_find
|
||||
#define sqlite3_vfs_register sqlite3_api->vfs_register
|
||||
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
|
||||
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
|
||||
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
|
||||
#define sqlite3_result_error_code sqlite3_api->result_error_code
|
||||
#define sqlite3_test_control sqlite3_api->test_control
|
||||
#define sqlite3_randomness sqlite3_api->randomness
|
||||
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
|
||||
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
|
||||
#define sqlite3_limit sqlite3_api->limit
|
||||
#define sqlite3_next_stmt sqlite3_api->next_stmt
|
||||
#define sqlite3_sql sqlite3_api->sql
|
||||
#define sqlite3_status sqlite3_api->status
|
||||
#define sqlite3_backup_finish sqlite3_api->backup_finish
|
||||
#define sqlite3_backup_init sqlite3_api->backup_init
|
||||
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
|
||||
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
|
||||
#define sqlite3_backup_step sqlite3_api->backup_step
|
||||
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
|
||||
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
|
||||
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
|
||||
#define sqlite3_db_config sqlite3_api->db_config
|
||||
#define sqlite3_db_mutex sqlite3_api->db_mutex
|
||||
#define sqlite3_db_status sqlite3_api->db_status
|
||||
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
|
||||
#define sqlite3_log sqlite3_api->log
|
||||
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
|
||||
#define sqlite3_sourceid sqlite3_api->sourceid
|
||||
#define sqlite3_stmt_status sqlite3_api->stmt_status
|
||||
#define sqlite3_strnicmp sqlite3_api->strnicmp
|
||||
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
|
||||
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
|
||||
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
|
||||
#define sqlite3_wal_hook sqlite3_api->wal_hook
|
||||
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
|
||||
#define sqlite3_vtab_config sqlite3_api->vtab_config
|
||||
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
|
||||
/* Version 3.7.16 and later */
|
||||
#define sqlite3_close_v2 sqlite3_api->close_v2
|
||||
#define sqlite3_db_filename sqlite3_api->db_filename
|
||||
#define sqlite3_db_readonly sqlite3_api->db_readonly
|
||||
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
|
||||
#define sqlite3_errstr sqlite3_api->errstr
|
||||
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
|
||||
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
|
||||
#define sqlite3_stricmp sqlite3_api->stricmp
|
||||
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
|
||||
#define sqlite3_uri_int64 sqlite3_api->uri_int64
|
||||
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
|
||||
/* Version 3.8.7 and later */
|
||||
#define sqlite3_auto_extension sqlite3_api->auto_extension
|
||||
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
|
||||
#define sqlite3_bind_text64 sqlite3_api->bind_text64
|
||||
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
|
||||
#define sqlite3_load_extension sqlite3_api->load_extension
|
||||
#define sqlite3_malloc64 sqlite3_api->malloc64
|
||||
#define sqlite3_msize sqlite3_api->msize
|
||||
#define sqlite3_realloc64 sqlite3_api->realloc64
|
||||
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
|
||||
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
|
||||
/* Version 3.9.0 and later */
|
||||
#define sqlite3_value_subtype sqlite3_api->value_subtype
|
||||
#define sqlite3_result_subtype sqlite3_api->result_subtype
|
||||
/* Version 3.10.0 and later */
|
||||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
/* Version 3.20.0 and later */
|
||||
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
|
||||
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
|
||||
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
|
||||
#define sqlite3_result_pointer sqlite3_api->result_pointer
|
||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||
/* Version 3.22.0 and later */
|
||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
||||
/* Version 3.24.0 and later */
|
||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
||||
#define sqlite3_str_new sqlite3_api->str_new
|
||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
||||
#define sqlite3_str_append sqlite3_api->str_append
|
||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
/* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
/* Version 3.38.0 and later */
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#define sqlite3_deserialize sqlite3_api->deserialize
|
||||
#define sqlite3_serialize sqlite3_api->serialize
|
||||
#endif
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
/* Version 3.44.0 and later */
|
||||
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
|
||||
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
|
||||
/* Version 3.50.0 and later */
|
||||
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
|
||||
/* Version 3.51.0 and later */
|
||||
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
|
||||
#define sqlite3_db_status64 sqlite3_api->db_status64
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE3EXT_H */
|
||||
@@ -1,690 +0,0 @@
|
||||
/*
|
||||
** 2010 April 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This file implements an example of a simple VFS implementation that
|
||||
** omits complex features often not required or not possible on embedded
|
||||
** platforms. Code is included to buffer writes to the journal file,
|
||||
** which can be a significant performance improvement on some embedded
|
||||
** platforms.
|
||||
**
|
||||
** OVERVIEW
|
||||
**
|
||||
** The code in this file implements a minimal SQLite VFS that can be
|
||||
** used on Linux and other posix-like operating systems. The following
|
||||
** system calls are used:
|
||||
**
|
||||
** File-system: access(), unlink(), getcwd()
|
||||
** File IO: open(), read(), write(), fsync(), close(), fstat()
|
||||
** Other: sleep(), usleep(), time()
|
||||
**
|
||||
** The following VFS features are omitted:
|
||||
**
|
||||
** 1. File locking. The user must ensure that there is at most one
|
||||
** connection to each database when using this VFS. Multiple
|
||||
** connections to a single shared-cache count as a single connection
|
||||
** for the purposes of the previous statement.
|
||||
**
|
||||
** 2. The loading of dynamic extensions (shared libraries).
|
||||
**
|
||||
** 3. Temporary files. The user must configure SQLite to use in-memory
|
||||
** temp files when using this VFS. The easiest way to do this is to
|
||||
** compile with:
|
||||
**
|
||||
** -DSQLITE_TEMP_STORE=3
|
||||
**
|
||||
** 4. File truncation. As of version 3.6.24, SQLite may run without
|
||||
** a working xTruncate() call, providing the user does not configure
|
||||
** SQLite to use "journal_mode=truncate", or use both
|
||||
** "journal_mode=persist" and ATTACHed databases.
|
||||
**
|
||||
** It is assumed that the system uses UNIX-like path-names. Specifically,
|
||||
** that '/' characters are used to separate path components and that
|
||||
** a path-name is a relative path unless it begins with a '/'. And that
|
||||
** no UTF-8 encoded paths are greater than 512 bytes in length.
|
||||
**
|
||||
** JOURNAL WRITE-BUFFERING
|
||||
**
|
||||
** To commit a transaction to the database, SQLite first writes rollback
|
||||
** information into the journal file. This usually consists of 4 steps:
|
||||
**
|
||||
** 1. The rollback information is sequentially written into the journal
|
||||
** file, starting at the start of the file.
|
||||
** 2. The journal file is synced to disk.
|
||||
** 3. A modification is made to the first few bytes of the journal file.
|
||||
** 4. The journal file is synced to disk again.
|
||||
**
|
||||
** Most of the data is written in step 1 using a series of calls to the
|
||||
** VFS xWrite() method. The buffers passed to the xWrite() calls are of
|
||||
** various sizes. For example, as of version 3.6.24, when committing a
|
||||
** transaction that modifies 3 pages of a database file that uses 4096
|
||||
** byte pages residing on a media with 512 byte sectors, SQLite makes
|
||||
** eleven calls to the xWrite() method to create the rollback journal,
|
||||
** as follows:
|
||||
**
|
||||
** Write offset | Bytes written
|
||||
** ----------------------------
|
||||
** 0 512
|
||||
** 512 4
|
||||
** 516 4096
|
||||
** 4612 4
|
||||
** 4616 4
|
||||
** 4620 4096
|
||||
** 8716 4
|
||||
** 8720 4
|
||||
** 8724 4096
|
||||
** 12820 4
|
||||
** ++++++++++++SYNC+++++++++++
|
||||
** 0 12
|
||||
** ++++++++++++SYNC+++++++++++
|
||||
**
|
||||
** On many operating systems, this is an efficient way to write to a file.
|
||||
** However, on some embedded systems that do not cache writes in OS
|
||||
** buffers it is much more efficient to write data in blocks that are
|
||||
** an integer multiple of the sector-size in size and aligned at the
|
||||
** start of a sector.
|
||||
**
|
||||
** To work around this, the code in this file allocates a fixed size
|
||||
** buffer of SQLITE_DEMOVFS_BUFFERSZ using sqlite3_malloc() whenever a
|
||||
** journal file is opened. It uses the buffer to coalesce sequential
|
||||
** writes into aligned SQLITE_DEMOVFS_BUFFERSZ blocks. When SQLite
|
||||
** invokes the xSync() method to sync the contents of the file to disk,
|
||||
** all accumulated data is written out, even if it does not constitute
|
||||
** a complete block. This means the actual IO to create the rollback
|
||||
** journal for the example transaction above is this:
|
||||
**
|
||||
** Write offset | Bytes written
|
||||
** ----------------------------
|
||||
** 0 8192
|
||||
** 8192 4632
|
||||
** ++++++++++++SYNC+++++++++++
|
||||
** 0 12
|
||||
** ++++++++++++SYNC+++++++++++
|
||||
**
|
||||
** Much more efficient if the underlying OS is not caching write
|
||||
** operations.
|
||||
*/
|
||||
|
||||
#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
** Size of the write buffer used by journal files in bytes.
|
||||
*/
|
||||
#ifndef SQLITE_DEMOVFS_BUFFERSZ
|
||||
# define SQLITE_DEMOVFS_BUFFERSZ 8192
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum pathname length supported by this VFS.
|
||||
*/
|
||||
#define MAXPATHNAME 512
|
||||
|
||||
/*
|
||||
** When using this VFS, the sqlite3_file* handles that SQLite uses are
|
||||
** actually pointers to instances of type DemoFile.
|
||||
*/
|
||||
typedef struct DemoFile DemoFile;
|
||||
struct DemoFile {
|
||||
sqlite3_file base; /* Base class. Must be first. */
|
||||
int fd; /* File descriptor */
|
||||
|
||||
char *aBuffer; /* Pointer to malloc'd buffer */
|
||||
int nBuffer; /* Valid bytes of data in zBuffer */
|
||||
sqlite3_int64 iBufferOfst; /* Offset in file of zBuffer[0] */
|
||||
};
|
||||
|
||||
/*
|
||||
** Write directly to the file passed as the first argument. Even if the
|
||||
** file has a write-buffer (DemoFile.aBuffer), ignore it.
|
||||
*/
|
||||
static int demoDirectWrite(
|
||||
DemoFile *p, /* File handle */
|
||||
const void *zBuf, /* Buffer containing data to write */
|
||||
int iAmt, /* Size of data to write in bytes */
|
||||
sqlite_int64 iOfst /* File offset to write to */
|
||||
){
|
||||
off_t ofst; /* Return value from lseek() */
|
||||
size_t nWrite; /* Return value from write() */
|
||||
|
||||
ofst = lseek(p->fd, iOfst, SEEK_SET);
|
||||
if( ofst!=iOfst ){
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
|
||||
nWrite = write(p->fd, zBuf, iAmt);
|
||||
if( nWrite!=iAmt ){
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the contents of the DemoFile.aBuffer buffer to disk. This is a
|
||||
** no-op if this particular file does not have a buffer (i.e. it is not
|
||||
** a journal file) or if the buffer is currently empty.
|
||||
*/
|
||||
static int demoFlushBuffer(DemoFile *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->nBuffer ){
|
||||
rc = demoDirectWrite(p, p->aBuffer, p->nBuffer, p->iBufferOfst);
|
||||
p->nBuffer = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
static int demoClose(sqlite3_file *pFile){
|
||||
int rc;
|
||||
DemoFile *p = (DemoFile*)pFile;
|
||||
rc = demoFlushBuffer(p);
|
||||
sqlite3_free(p->aBuffer);
|
||||
close(p->fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read data from a file.
|
||||
*/
|
||||
static int demoRead(
|
||||
sqlite3_file *pFile,
|
||||
void *zBuf,
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
DemoFile *p = (DemoFile*)pFile;
|
||||
off_t ofst; /* Return value from lseek() */
|
||||
int nRead; /* Return value from read() */
|
||||
int rc; /* Return code from demoFlushBuffer() */
|
||||
|
||||
/* Flush any data in the write buffer to disk in case this operation
|
||||
** is trying to read data the file-region currently cached in the buffer.
|
||||
** It would be possible to detect this case and possibly save an
|
||||
** unnecessary write here, but in practice SQLite will rarely read from
|
||||
** a journal file when there is data cached in the write-buffer.
|
||||
*/
|
||||
rc = demoFlushBuffer(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
ofst = lseek(p->fd, iOfst, SEEK_SET);
|
||||
if( ofst!=iOfst ){
|
||||
return SQLITE_IOERR_READ;
|
||||
}
|
||||
nRead = read(p->fd, zBuf, iAmt);
|
||||
|
||||
if( nRead==iAmt ){
|
||||
return SQLITE_OK;
|
||||
}else if( nRead>=0 ){
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
|
||||
return SQLITE_IOERR_READ;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write data to a crash-file.
|
||||
*/
|
||||
static int demoWrite(
|
||||
sqlite3_file *pFile,
|
||||
const void *zBuf,
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
DemoFile *p = (DemoFile*)pFile;
|
||||
|
||||
if( p->aBuffer ){
|
||||
char *z = (char *)zBuf; /* Pointer to remaining data to write */
|
||||
int n = iAmt; /* Number of bytes at z */
|
||||
sqlite3_int64 i = iOfst; /* File offset to write to */
|
||||
|
||||
while( n>0 ){
|
||||
int nCopy; /* Number of bytes to copy into buffer */
|
||||
|
||||
/* If the buffer is full, or if this data is not being written directly
|
||||
** following the data already buffered, flush the buffer. Flushing
|
||||
** the buffer is a no-op if it is empty.
|
||||
*/
|
||||
if( p->nBuffer==SQLITE_DEMOVFS_BUFFERSZ || p->iBufferOfst+p->nBuffer!=i ){
|
||||
int rc = demoFlushBuffer(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
assert( p->nBuffer==0 || p->iBufferOfst+p->nBuffer==i );
|
||||
p->iBufferOfst = i - p->nBuffer;
|
||||
|
||||
/* Copy as much data as possible into the buffer. */
|
||||
nCopy = SQLITE_DEMOVFS_BUFFERSZ - p->nBuffer;
|
||||
if( nCopy>n ){
|
||||
nCopy = n;
|
||||
}
|
||||
memcpy(&p->aBuffer[p->nBuffer], z, nCopy);
|
||||
p->nBuffer += nCopy;
|
||||
|
||||
n -= nCopy;
|
||||
i += nCopy;
|
||||
z += nCopy;
|
||||
}
|
||||
}else{
|
||||
return demoDirectWrite(p, zBuf, iAmt, iOfst);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate a file. This is a no-op for this VFS (see header comments at
|
||||
** the top of the file).
|
||||
*/
|
||||
static int demoTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
#if 0
|
||||
if( ftruncate(((DemoFile *)pFile)->fd, size) ) return SQLITE_IOERR_TRUNCATE;
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sync the contents of the file to the persistent media.
|
||||
*/
|
||||
static int demoSync(sqlite3_file *pFile, int flags){
|
||||
DemoFile *p = (DemoFile*)pFile;
|
||||
int rc;
|
||||
|
||||
rc = demoFlushBuffer(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = fsync(p->fd);
|
||||
return (rc==0 ? SQLITE_OK : SQLITE_IOERR_FSYNC);
|
||||
}
|
||||
|
||||
/*
|
||||
** Write the size of the file in bytes to *pSize.
|
||||
*/
|
||||
static int demoFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||
DemoFile *p = (DemoFile*)pFile;
|
||||
int rc; /* Return code from fstat() call */
|
||||
struct stat sStat; /* Output of fstat() call */
|
||||
|
||||
/* Flush the contents of the buffer to disk. As with the flush in the
|
||||
** demoRead() method, it would be possible to avoid this and save a write
|
||||
** here and there. But in practice this comes up so infrequently it is
|
||||
** not worth the trouble.
|
||||
*/
|
||||
rc = demoFlushBuffer(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = fstat(p->fd, &sStat);
|
||||
if( rc!=0 ) return SQLITE_IOERR_FSTAT;
|
||||
*pSize = sStat.st_size;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Locking functions. The xLock() and xUnlock() methods are both no-ops.
|
||||
** The xCheckReservedLock() always indicates that no other process holds
|
||||
** a reserved lock on the database file. This ensures that if a hot-journal
|
||||
** file is found in the file-system it is rolled back.
|
||||
*/
|
||||
static int demoLock(sqlite3_file *pFile, int eLock){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static int demoUnlock(sqlite3_file *pFile, int eLock){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static int demoCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||
*pResOut = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** No xFileControl() verbs are implemented by this VFS.
|
||||
*/
|
||||
static int demoFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** The xSectorSize() and xDeviceCharacteristics() methods. These two
|
||||
** may return special values allowing SQLite to optimize file-system
|
||||
** access to some extent. But it is also safe to simply return 0.
|
||||
*/
|
||||
static int demoSectorSize(sqlite3_file *pFile){
|
||||
return 0;
|
||||
}
|
||||
static int demoDeviceCharacteristics(sqlite3_file *pFile){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a file handle.
|
||||
*/
|
||||
static int demoOpen(
|
||||
sqlite3_vfs *pVfs, /* VFS */
|
||||
const char *zName, /* File to open, or 0 for a temp file */
|
||||
sqlite3_file *pFile, /* Pointer to DemoFile struct to populate */
|
||||
int flags, /* Input SQLITE_OPEN_XXX flags */
|
||||
int *pOutFlags /* Output SQLITE_OPEN_XXX flags (or NULL) */
|
||||
){
|
||||
static const sqlite3_io_methods demoio = {
|
||||
1, /* iVersion */
|
||||
demoClose, /* xClose */
|
||||
demoRead, /* xRead */
|
||||
demoWrite, /* xWrite */
|
||||
demoTruncate, /* xTruncate */
|
||||
demoSync, /* xSync */
|
||||
demoFileSize, /* xFileSize */
|
||||
demoLock, /* xLock */
|
||||
demoUnlock, /* xUnlock */
|
||||
demoCheckReservedLock, /* xCheckReservedLock */
|
||||
demoFileControl, /* xFileControl */
|
||||
demoSectorSize, /* xSectorSize */
|
||||
demoDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
};
|
||||
|
||||
DemoFile *p = (DemoFile*)pFile; /* Populate this structure */
|
||||
int oflags = 0; /* flags to pass to open() call */
|
||||
char *aBuf = 0;
|
||||
|
||||
if( zName==0 ){
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
|
||||
if( flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
aBuf = (char *)sqlite3_malloc(SQLITE_DEMOVFS_BUFFERSZ);
|
||||
if( !aBuf ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if( flags&SQLITE_OPEN_EXCLUSIVE ) oflags |= O_EXCL;
|
||||
if( flags&SQLITE_OPEN_CREATE ) oflags |= O_CREAT;
|
||||
if( flags&SQLITE_OPEN_READONLY ) oflags |= O_RDONLY;
|
||||
if( flags&SQLITE_OPEN_READWRITE ) oflags |= O_RDWR;
|
||||
|
||||
memset(p, 0, sizeof(DemoFile));
|
||||
p->fd = open(zName, oflags, 0600);
|
||||
if( p->fd<0 ){
|
||||
sqlite3_free(aBuf);
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
p->aBuffer = aBuf;
|
||||
|
||||
if( pOutFlags ){
|
||||
*pOutFlags = flags;
|
||||
}
|
||||
p->base.pMethods = &demoio;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Delete the file identified by argument zPath. If the dirSync parameter
|
||||
** is non-zero, then ensure the file-system modification to delete the
|
||||
** file has been synced to disk before returning.
|
||||
*/
|
||||
static int demoDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||
int rc; /* Return code */
|
||||
|
||||
rc = unlink(zPath);
|
||||
if( rc!=0 && errno==ENOENT ) return SQLITE_OK;
|
||||
|
||||
if( rc==0 && dirSync ){
|
||||
int dfd; /* File descriptor open on directory */
|
||||
int i; /* Iterator variable */
|
||||
char zDir[MAXPATHNAME+1]; /* Name of directory containing file zPath */
|
||||
|
||||
/* Figure out the directory name from the path of the file deleted. */
|
||||
sqlite3_snprintf(MAXPATHNAME, zDir, "%s", zPath);
|
||||
zDir[MAXPATHNAME] = '\0';
|
||||
for(i=strlen(zDir); i>1 && zDir[i]!='/'; i++);
|
||||
zDir[i] = '\0';
|
||||
|
||||
/* Open a file-descriptor on the directory. Sync. Close. */
|
||||
dfd = open(zDir, O_RDONLY, 0);
|
||||
if( dfd<0 ){
|
||||
rc = -1;
|
||||
}else{
|
||||
rc = fsync(dfd);
|
||||
close(dfd);
|
||||
}
|
||||
}
|
||||
return (rc==0 ? SQLITE_OK : SQLITE_IOERR_DELETE);
|
||||
}
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
# define R_OK 4
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
# define W_OK 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Query the file-system to see if the named file exists, is readable or
|
||||
** is both readable and writable.
|
||||
*/
|
||||
static int demoAccess(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zPath,
|
||||
int flags,
|
||||
int *pResOut
|
||||
){
|
||||
int rc; /* access() return code */
|
||||
int eAccess = F_OK; /* Second argument to access() */
|
||||
|
||||
assert( flags==SQLITE_ACCESS_EXISTS /* access(zPath, F_OK) */
|
||||
|| flags==SQLITE_ACCESS_READ /* access(zPath, R_OK) */
|
||||
|| flags==SQLITE_ACCESS_READWRITE /* access(zPath, R_OK|W_OK) */
|
||||
);
|
||||
|
||||
if( flags==SQLITE_ACCESS_READWRITE ) eAccess = R_OK|W_OK;
|
||||
if( flags==SQLITE_ACCESS_READ ) eAccess = R_OK;
|
||||
|
||||
rc = access(zPath, eAccess);
|
||||
*pResOut = (rc==0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument zPath points to a nul-terminated string containing a file path.
|
||||
** If zPath is an absolute path, then it is copied as is into the output
|
||||
** buffer. Otherwise, if it is a relative path, then the equivalent full
|
||||
** path is written to the output buffer.
|
||||
**
|
||||
** This function assumes that paths are UNIX style. Specifically, that:
|
||||
**
|
||||
** 1. Path components are separated by a '/'. and
|
||||
** 2. Full paths begin with a '/' character.
|
||||
*/
|
||||
static int demoFullPathname(
|
||||
sqlite3_vfs *pVfs, /* VFS */
|
||||
const char *zPath, /* Input path (possibly a relative path) */
|
||||
int nPathOut, /* Size of output buffer in bytes */
|
||||
char *zPathOut /* Pointer to output buffer */
|
||||
){
|
||||
sqlite3_snprintf(nPathOut, zPathOut, "%s", zPath);
|
||||
zPathOut[nPathOut-1] = '\0';
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** The following four VFS methods:
|
||||
**
|
||||
** xDlOpen
|
||||
** xDlError
|
||||
** xDlSym
|
||||
** xDlClose
|
||||
**
|
||||
** are supposed to implement the functionality needed by SQLite to load
|
||||
** extensions compiled as shared objects. This simple VFS does not support
|
||||
** this functionality, so the following functions are no-ops.
|
||||
*/
|
||||
static void *demoDlOpen(sqlite3_vfs *pVfs, const char *zPath){
|
||||
return 0;
|
||||
}
|
||||
static void demoDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
|
||||
sqlite3_snprintf(nByte, zErrMsg, "Loadable extensions are not supported");
|
||||
zErrMsg[nByte-1] = '\0';
|
||||
}
|
||||
static void (*demoDlSym(sqlite3_vfs *pVfs, void *pH, const char *z))(void){
|
||||
return 0;
|
||||
}
|
||||
static void demoDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Parameter zByte points to a buffer nByte bytes in size. Populate this
|
||||
** buffer with pseudo-random data.
|
||||
*/
|
||||
static int demoRandomness(sqlite3_vfs *pVfs, int nByte, char *zByte){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sleep for at least nMicro microseconds. Return the (approximate) number
|
||||
** of microseconds slept for.
|
||||
*/
|
||||
static int demoSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||
sleep(nMicro / 1000000);
|
||||
usleep(nMicro % 1000000);
|
||||
return nMicro;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set *pTime to the current UTC time expressed as a Julian day. Return
|
||||
** SQLITE_OK if successful, or an error code otherwise.
|
||||
**
|
||||
** http://en.wikipedia.org/wiki/Julian_day
|
||||
**
|
||||
** This implementation is not very good. The current time is rounded to
|
||||
** an integer number of seconds. Also, assuming time_t is a signed 32-bit
|
||||
** value, it will stop working some time in the year 2038 AD (the so-called
|
||||
** "year 2038" problem that afflicts systems that store time this way).
|
||||
*/
|
||||
static int demoCurrentTime(sqlite3_vfs *pVfs, double *pTime){
|
||||
time_t t = time(0);
|
||||
*pTime = t/86400.0 + 2440587.5;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function returns a pointer to the VFS implemented in this file.
|
||||
** To make the VFS available to SQLite:
|
||||
**
|
||||
** sqlite3_vfs_register(sqlite3_demovfs(), 0);
|
||||
*/
|
||||
sqlite3_vfs *sqlite3_demovfs(void){
|
||||
static sqlite3_vfs demovfs = {
|
||||
1, /* iVersion */
|
||||
sizeof(DemoFile), /* szOsFile */
|
||||
MAXPATHNAME, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"demo", /* zName */
|
||||
0, /* pAppData */
|
||||
demoOpen, /* xOpen */
|
||||
demoDelete, /* xDelete */
|
||||
demoAccess, /* xAccess */
|
||||
demoFullPathname, /* xFullPathname */
|
||||
demoDlOpen, /* xDlOpen */
|
||||
demoDlError, /* xDlError */
|
||||
demoDlSym, /* xDlSym */
|
||||
demoDlClose, /* xDlClose */
|
||||
demoRandomness, /* xRandomness */
|
||||
demoSleep, /* xSleep */
|
||||
demoCurrentTime, /* xCurrentTime */
|
||||
};
|
||||
return &demovfs;
|
||||
}
|
||||
|
||||
#endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */
|
||||
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
|
||||
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||
# include "sqlite_tcl.h"
|
||||
#else
|
||||
# include "tcl.h"
|
||||
# ifndef SQLITE_TCLAPI
|
||||
# define SQLITE_TCLAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_UNIX
|
||||
static int SQLITE_TCLAPI register_demovfs(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_vfs_register(sqlite3_demovfs(), 1);
|
||||
return TCL_OK;
|
||||
}
|
||||
static int SQLITE_TCLAPI unregister_demovfs(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_vfs_unregister(sqlite3_demovfs());
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
*/
|
||||
int Sqlitetest_demovfs_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(interp, "register_demovfs", register_demovfs, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "unregister_demovfs", unregister_demovfs, 0, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
int Sqlitetest_demovfs_Init(Tcl_Interp *interp){ return TCL_OK; }
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE_TEST */
|
||||
|
||||
// Register sqlite3_demovfs
|
||||
int sqlite3_os_init()
|
||||
{
|
||||
sqlite3_vfs_register(sqlite3_demovfs(), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sqlite3_os_end()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
-343
@@ -1,343 +0,0 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Error Codes
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum ErrorCode {
|
||||
/// Internal logic error in SQLite
|
||||
InternalMalfunction,
|
||||
/// Access permission denied
|
||||
PermissionDenied,
|
||||
/// Callback routine requested an abort
|
||||
OperationAborted,
|
||||
/// The database file is locked
|
||||
DatabaseBusy,
|
||||
/// A table in the database is locked
|
||||
DatabaseLocked,
|
||||
/// A malloc() failed
|
||||
OutOfMemory,
|
||||
/// Attempt to write a readonly database
|
||||
ReadOnly,
|
||||
/// Operation terminated by sqlite3_interrupt()
|
||||
OperationInterrupted,
|
||||
/// Some kind of disk I/O error occurred
|
||||
SystemIoFailure,
|
||||
/// The database disk image is malformed
|
||||
DatabaseCorrupt,
|
||||
/// Unknown opcode in sqlite3_file_control()
|
||||
NotFound,
|
||||
/// Insertion failed because database is full
|
||||
DiskFull,
|
||||
/// Unable to open the database file
|
||||
CannotOpen,
|
||||
/// Database lock protocol error
|
||||
FileLockingProtocolFailed,
|
||||
/// The database schema changed
|
||||
SchemaChanged,
|
||||
/// String or BLOB exceeds size limit
|
||||
TooBig,
|
||||
/// Abort due to constraint violation
|
||||
ConstraintViolation,
|
||||
/// Data type mismatch
|
||||
TypeMismatch,
|
||||
/// Library used incorrectly
|
||||
ApiMisuse,
|
||||
/// Uses OS features not supported on host
|
||||
NoLargeFileSupport,
|
||||
/// Authorization denied
|
||||
AuthorizationForStatementDenied,
|
||||
/// 2nd parameter to sqlite3_bind out of range
|
||||
ParameterOutOfRange,
|
||||
/// File opened that is not a database file
|
||||
NotADatabase,
|
||||
/// SQL error or missing database
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Error {
|
||||
pub code: ErrorCode,
|
||||
pub extended_code: c_int,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
#[must_use]
|
||||
pub fn new(result_code: c_int) -> Error {
|
||||
let code = match result_code & 0xff {
|
||||
super::SQLITE_INTERNAL => ErrorCode::InternalMalfunction,
|
||||
super::SQLITE_PERM => ErrorCode::PermissionDenied,
|
||||
super::SQLITE_ABORT => ErrorCode::OperationAborted,
|
||||
super::SQLITE_BUSY => ErrorCode::DatabaseBusy,
|
||||
super::SQLITE_LOCKED => ErrorCode::DatabaseLocked,
|
||||
super::SQLITE_NOMEM => ErrorCode::OutOfMemory,
|
||||
super::SQLITE_READONLY => ErrorCode::ReadOnly,
|
||||
super::SQLITE_INTERRUPT => ErrorCode::OperationInterrupted,
|
||||
super::SQLITE_IOERR => ErrorCode::SystemIoFailure,
|
||||
super::SQLITE_CORRUPT => ErrorCode::DatabaseCorrupt,
|
||||
super::SQLITE_NOTFOUND => ErrorCode::NotFound,
|
||||
super::SQLITE_FULL => ErrorCode::DiskFull,
|
||||
super::SQLITE_CANTOPEN => ErrorCode::CannotOpen,
|
||||
super::SQLITE_PROTOCOL => ErrorCode::FileLockingProtocolFailed,
|
||||
super::SQLITE_SCHEMA => ErrorCode::SchemaChanged,
|
||||
super::SQLITE_TOOBIG => ErrorCode::TooBig,
|
||||
super::SQLITE_CONSTRAINT => ErrorCode::ConstraintViolation,
|
||||
super::SQLITE_MISMATCH => ErrorCode::TypeMismatch,
|
||||
super::SQLITE_MISUSE => ErrorCode::ApiMisuse,
|
||||
super::SQLITE_NOLFS => ErrorCode::NoLargeFileSupport,
|
||||
super::SQLITE_AUTH => ErrorCode::AuthorizationForStatementDenied,
|
||||
super::SQLITE_RANGE => ErrorCode::ParameterOutOfRange,
|
||||
super::SQLITE_NOTADB => ErrorCode::NotADatabase,
|
||||
_ => ErrorCode::Unknown,
|
||||
};
|
||||
|
||||
Error {
|
||||
code,
|
||||
extended_code: result_code,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Error code {}: {}",
|
||||
self.extended_code,
|
||||
code_to_str(self.extended_code)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
code_to_str(self.extended_code)
|
||||
}
|
||||
}
|
||||
|
||||
// Result codes.
|
||||
// Note: These are not public because our bindgen bindings export whichever
|
||||
// constants are present in the current version of SQLite. We repeat them here,
|
||||
// so we don't have to worry about which version of SQLite added which
|
||||
// constants, and we only use them to implement code_to_str below.
|
||||
|
||||
// Extended result codes.
|
||||
|
||||
const SQLITE_ERROR_MISSING_COLLSEQ: c_int = super::SQLITE_ERROR | (1 << 8);
|
||||
const SQLITE_ERROR_RETRY: c_int = super::SQLITE_ERROR | (2 << 8);
|
||||
const SQLITE_ERROR_SNAPSHOT: c_int = super::SQLITE_ERROR | (3 << 8);
|
||||
|
||||
const SQLITE_IOERR_BEGIN_ATOMIC: c_int = super::SQLITE_IOERR | (29 << 8);
|
||||
const SQLITE_IOERR_COMMIT_ATOMIC: c_int = super::SQLITE_IOERR | (30 << 8);
|
||||
const SQLITE_IOERR_ROLLBACK_ATOMIC: c_int = super::SQLITE_IOERR | (31 << 8);
|
||||
const SQLITE_IOERR_DATA: c_int = super::SQLITE_IOERR | (32 << 8);
|
||||
const SQLITE_IOERR_CORRUPTFS: c_int = super::SQLITE_IOERR | (33 << 8);
|
||||
const SQLITE_IOERR_IN_PAGE: c_int = super::SQLITE_IOERR | (34 << 8);
|
||||
|
||||
const SQLITE_LOCKED_VTAB: c_int = super::SQLITE_LOCKED | (2 << 8);
|
||||
|
||||
const SQLITE_BUSY_TIMEOUT: c_int = super::SQLITE_BUSY | (3 << 8);
|
||||
|
||||
const SQLITE_CANTOPEN_SYMLINK: c_int = super::SQLITE_CANTOPEN | (6 << 8);
|
||||
|
||||
const SQLITE_CORRUPT_SEQUENCE: c_int = super::SQLITE_CORRUPT | (2 << 8);
|
||||
const SQLITE_CORRUPT_INDEX: c_int = super::SQLITE_CORRUPT | (3 << 8);
|
||||
|
||||
const SQLITE_READONLY_CANTINIT: c_int = super::SQLITE_READONLY | (5 << 8);
|
||||
const SQLITE_READONLY_DIRECTORY: c_int = super::SQLITE_READONLY | (6 << 8);
|
||||
|
||||
const SQLITE_CONSTRAINT_PINNED: c_int = super::SQLITE_CONSTRAINT | (11 << 8);
|
||||
const SQLITE_CONSTRAINT_DATATYPE: c_int = super::SQLITE_CONSTRAINT | (12 << 8);
|
||||
|
||||
#[must_use]
|
||||
pub fn code_to_str(code: c_int) -> &'static str {
|
||||
match code {
|
||||
super::SQLITE_OK => "Successful result",
|
||||
super::SQLITE_ERROR => "SQL error or missing database",
|
||||
super::SQLITE_INTERNAL => "Internal logic error in SQLite",
|
||||
super::SQLITE_PERM => "Access permission denied",
|
||||
super::SQLITE_ABORT => "Callback routine requested an abort",
|
||||
super::SQLITE_BUSY => "The database file is locked",
|
||||
super::SQLITE_LOCKED => "A table in the database is locked",
|
||||
super::SQLITE_NOMEM => "A malloc() failed",
|
||||
super::SQLITE_READONLY => "Attempt to write a readonly database",
|
||||
super::SQLITE_INTERRUPT => "Operation terminated by sqlite3_interrupt()",
|
||||
super::SQLITE_IOERR => "Some kind of disk I/O error occurred",
|
||||
super::SQLITE_CORRUPT => "The database disk image is malformed",
|
||||
super::SQLITE_NOTFOUND => "Unknown opcode in sqlite3_file_control()",
|
||||
super::SQLITE_FULL => "Insertion failed because database is full",
|
||||
super::SQLITE_CANTOPEN => "Unable to open the database file",
|
||||
super::SQLITE_PROTOCOL => "Database lock protocol error",
|
||||
super::SQLITE_EMPTY => "Database is empty",
|
||||
super::SQLITE_SCHEMA => "The database schema changed",
|
||||
super::SQLITE_TOOBIG => "String or BLOB exceeds size limit",
|
||||
super::SQLITE_CONSTRAINT=> "Abort due to constraint violation",
|
||||
super::SQLITE_MISMATCH => "Data type mismatch",
|
||||
super::SQLITE_MISUSE => "Library used incorrectly",
|
||||
super::SQLITE_NOLFS => "Uses OS features not supported on host",
|
||||
super::SQLITE_AUTH => "Authorization denied",
|
||||
super::SQLITE_FORMAT => "Auxiliary database format error",
|
||||
super::SQLITE_RANGE => "2nd parameter to sqlite3_bind out of range",
|
||||
super::SQLITE_NOTADB => "File opened that is not a database file",
|
||||
super::SQLITE_NOTICE => "Notifications from sqlite3_log()",
|
||||
super::SQLITE_WARNING => "Warnings from sqlite3_log()",
|
||||
super::SQLITE_ROW => "sqlite3_step() has another row ready",
|
||||
super::SQLITE_DONE => "sqlite3_step() has finished executing",
|
||||
|
||||
SQLITE_ERROR_MISSING_COLLSEQ => "SQLITE_ERROR_MISSING_COLLSEQ",
|
||||
SQLITE_ERROR_RETRY => "SQLITE_ERROR_RETRY",
|
||||
SQLITE_ERROR_SNAPSHOT => "SQLITE_ERROR_SNAPSHOT",
|
||||
|
||||
super::SQLITE_IOERR_READ => "Error reading from disk",
|
||||
super::SQLITE_IOERR_SHORT_READ => "Unable to obtain number of requested bytes (file truncated?)",
|
||||
super::SQLITE_IOERR_WRITE => "Error writing to disk",
|
||||
super::SQLITE_IOERR_FSYNC => "Error flushing data to persistent storage (fsync)",
|
||||
super::SQLITE_IOERR_DIR_FSYNC => "Error calling fsync on a directory",
|
||||
super::SQLITE_IOERR_TRUNCATE => "Error attempting to truncate file",
|
||||
super::SQLITE_IOERR_FSTAT => "Error invoking fstat to get file metadata",
|
||||
super::SQLITE_IOERR_UNLOCK => "I/O error within xUnlock of a VFS object",
|
||||
super::SQLITE_IOERR_RDLOCK => "I/O error within xLock of a VFS object (trying to obtain a read lock)",
|
||||
super::SQLITE_IOERR_DELETE => "I/O error within xDelete of a VFS object",
|
||||
super::SQLITE_IOERR_BLOCKED => "SQLITE_IOERR_BLOCKED", // no longer used
|
||||
super::SQLITE_IOERR_NOMEM => "Out of memory in I/O layer",
|
||||
super::SQLITE_IOERR_ACCESS => "I/O error within xAccess of a VFS object",
|
||||
super::SQLITE_IOERR_CHECKRESERVEDLOCK => "I/O error within then xCheckReservedLock method",
|
||||
super::SQLITE_IOERR_LOCK => "I/O error in the advisory file locking layer",
|
||||
super::SQLITE_IOERR_CLOSE => "I/O error within the xClose method",
|
||||
super::SQLITE_IOERR_DIR_CLOSE => "SQLITE_IOERR_DIR_CLOSE", // no longer used
|
||||
super::SQLITE_IOERR_SHMOPEN => "I/O error within the xShmMap method (trying to open a new shared-memory segment)",
|
||||
super::SQLITE_IOERR_SHMSIZE => "I/O error within the xShmMap method (trying to resize an existing shared-memory segment)",
|
||||
super::SQLITE_IOERR_SHMLOCK => "SQLITE_IOERR_SHMLOCK", // no longer used
|
||||
super::SQLITE_IOERR_SHMMAP => "I/O error within the xShmMap method (trying to map a shared-memory segment into process address space)",
|
||||
super::SQLITE_IOERR_SEEK => "I/O error within the xRead or xWrite (trying to seek within a file)",
|
||||
super::SQLITE_IOERR_DELETE_NOENT => "File being deleted does not exist",
|
||||
super::SQLITE_IOERR_MMAP => "I/O error while trying to map or unmap part of the database file into process address space",
|
||||
super::SQLITE_IOERR_GETTEMPPATH => "VFS is unable to determine a suitable directory for temporary files",
|
||||
super::SQLITE_IOERR_CONVPATH => "cygwin_conv_path() system call failed",
|
||||
super::SQLITE_IOERR_VNODE => "SQLITE_IOERR_VNODE", // not documented?
|
||||
super::SQLITE_IOERR_AUTH => "SQLITE_IOERR_AUTH",
|
||||
SQLITE_IOERR_BEGIN_ATOMIC => "SQLITE_IOERR_BEGIN_ATOMIC",
|
||||
SQLITE_IOERR_COMMIT_ATOMIC => "SQLITE_IOERR_COMMIT_ATOMIC",
|
||||
SQLITE_IOERR_ROLLBACK_ATOMIC => "SQLITE_IOERR_ROLLBACK_ATOMIC",
|
||||
SQLITE_IOERR_DATA => "SQLITE_IOERR_DATA",
|
||||
SQLITE_IOERR_CORRUPTFS => "SQLITE_IOERR_CORRUPTFS",
|
||||
SQLITE_IOERR_IN_PAGE => "SQLITE_IOERR_IN_PAGE",
|
||||
|
||||
super::SQLITE_LOCKED_SHAREDCACHE => "Locking conflict due to another connection with a shared cache",
|
||||
SQLITE_LOCKED_VTAB => "SQLITE_LOCKED_VTAB",
|
||||
|
||||
super::SQLITE_BUSY_RECOVERY => "Another process is recovering a WAL mode database file",
|
||||
super::SQLITE_BUSY_SNAPSHOT => "Cannot promote read transaction to write transaction because of writes by another connection",
|
||||
SQLITE_BUSY_TIMEOUT => "SQLITE_BUSY_TIMEOUT",
|
||||
|
||||
super::SQLITE_CANTOPEN_NOTEMPDIR => "SQLITE_CANTOPEN_NOTEMPDIR", // no longer used
|
||||
super::SQLITE_CANTOPEN_ISDIR => "Attempted to open directory as file",
|
||||
super::SQLITE_CANTOPEN_FULLPATH => "Unable to convert filename into full pathname",
|
||||
super::SQLITE_CANTOPEN_CONVPATH => "cygwin_conv_path() system call failed",
|
||||
SQLITE_CANTOPEN_SYMLINK => "SQLITE_CANTOPEN_SYMLINK",
|
||||
|
||||
super::SQLITE_CORRUPT_VTAB => "Content in the virtual table is corrupt",
|
||||
SQLITE_CORRUPT_SEQUENCE => "SQLITE_CORRUPT_SEQUENCE",
|
||||
SQLITE_CORRUPT_INDEX => "SQLITE_CORRUPT_INDEX",
|
||||
|
||||
super::SQLITE_READONLY_RECOVERY => "WAL mode database file needs recovery (requires write access)",
|
||||
super::SQLITE_READONLY_CANTLOCK => "Shared-memory file associated with WAL mode database is read-only",
|
||||
super::SQLITE_READONLY_ROLLBACK => "Database has hot journal that must be rolled back (requires write access)",
|
||||
super::SQLITE_READONLY_DBMOVED => "Database cannot be modified because database file has moved",
|
||||
SQLITE_READONLY_CANTINIT => "SQLITE_READONLY_CANTINIT",
|
||||
SQLITE_READONLY_DIRECTORY => "SQLITE_READONLY_DIRECTORY",
|
||||
|
||||
super::SQLITE_ABORT_ROLLBACK => "Transaction was rolled back",
|
||||
|
||||
super::SQLITE_CONSTRAINT_CHECK => "A CHECK constraint failed",
|
||||
super::SQLITE_CONSTRAINT_COMMITHOOK => "Commit hook caused rollback",
|
||||
super::SQLITE_CONSTRAINT_FOREIGNKEY => "Foreign key constraint failed",
|
||||
super::SQLITE_CONSTRAINT_FUNCTION => "Error returned from extension function",
|
||||
super::SQLITE_CONSTRAINT_NOTNULL => "A NOT NULL constraint failed",
|
||||
super::SQLITE_CONSTRAINT_PRIMARYKEY => "A PRIMARY KEY constraint failed",
|
||||
super::SQLITE_CONSTRAINT_TRIGGER => "A RAISE function within a trigger fired",
|
||||
super::SQLITE_CONSTRAINT_UNIQUE => "A UNIQUE constraint failed",
|
||||
super::SQLITE_CONSTRAINT_VTAB => "An application-defined virtual table error occurred",
|
||||
super::SQLITE_CONSTRAINT_ROWID => "A non-unique rowid occurred",
|
||||
SQLITE_CONSTRAINT_PINNED => "SQLITE_CONSTRAINT_PINNED",
|
||||
SQLITE_CONSTRAINT_DATATYPE => "SQLITE_CONSTRAINT_DATATYPE",
|
||||
|
||||
super::SQLITE_NOTICE_RECOVER_WAL => "A WAL mode database file was recovered",
|
||||
super::SQLITE_NOTICE_RECOVER_ROLLBACK => "Hot journal was rolled back",
|
||||
|
||||
super::SQLITE_WARNING_AUTOINDEX => "Automatic indexing used - database might benefit from additional indexes",
|
||||
|
||||
super::SQLITE_AUTH_USER => "SQLITE_AUTH_USER", // not documented?
|
||||
|
||||
_ => "Unknown error code",
|
||||
}
|
||||
}
|
||||
|
||||
/// Loadable extension initialization error
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum InitError {
|
||||
/// Version mismatch between the extension and the SQLite3 library
|
||||
VersionMismatch { compile_time: i32, runtime: i32 },
|
||||
/// Invalid function pointer in one of sqlite3_api_routines fields
|
||||
NullFunctionPointer,
|
||||
}
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
impl ::std::fmt::Display for InitError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
InitError::VersionMismatch {
|
||||
compile_time,
|
||||
runtime,
|
||||
} => {
|
||||
write!(f, "SQLite version mismatch: {runtime} < {compile_time}")
|
||||
}
|
||||
InitError::NullFunctionPointer => {
|
||||
write!(f, "Some sqlite3_api_routines fields are null")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
impl error::Error for InitError {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
pub fn error_new() {
|
||||
let assoc = vec![
|
||||
(SQLITE_INTERNAL, ErrorCode::InternalMalfunction),
|
||||
(SQLITE_PERM, ErrorCode::PermissionDenied),
|
||||
(SQLITE_ABORT_ROLLBACK, ErrorCode::OperationAborted),
|
||||
(SQLITE_BUSY_RECOVERY, ErrorCode::DatabaseBusy),
|
||||
(SQLITE_LOCKED_SHAREDCACHE, ErrorCode::DatabaseLocked),
|
||||
(SQLITE_NOMEM, ErrorCode::OutOfMemory),
|
||||
(SQLITE_IOERR_READ, ErrorCode::SystemIoFailure),
|
||||
(SQLITE_NOTFOUND, ErrorCode::NotFound),
|
||||
(SQLITE_FULL, ErrorCode::DiskFull),
|
||||
(SQLITE_PROTOCOL, ErrorCode::FileLockingProtocolFailed),
|
||||
(SQLITE_SCHEMA, ErrorCode::SchemaChanged),
|
||||
(SQLITE_TOOBIG, ErrorCode::TooBig),
|
||||
(SQLITE_MISMATCH, ErrorCode::TypeMismatch),
|
||||
(SQLITE_NOLFS, ErrorCode::NoLargeFileSupport),
|
||||
(SQLITE_RANGE, ErrorCode::ParameterOutOfRange),
|
||||
(SQLITE_NOTADB, ErrorCode::NotADatabase),
|
||||
];
|
||||
for (sqlite_code, rust_code) in assoc {
|
||||
let err = Error::new(sqlite_code);
|
||||
assert_eq!(
|
||||
err,
|
||||
Error {
|
||||
code: rust_code,
|
||||
extended_code: sqlite_code
|
||||
}
|
||||
);
|
||||
let s = format!("{}", err);
|
||||
assert!(!s.is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
#![allow(non_snake_case, non_camel_case_types)]
|
||||
#![cfg_attr(test, allow(deref_nullptr))] // https://github.com/rust-lang/rust-bindgen/issues/2066
|
||||
|
||||
// force linking to openssl
|
||||
#[cfg(feature = "bundled-sqlcipher-vendored-openssl")]
|
||||
extern crate openssl_sys;
|
||||
|
||||
pub use self::error::*;
|
||||
|
||||
use std::mem;
|
||||
|
||||
mod error;
|
||||
|
||||
#[must_use]
|
||||
pub fn SQLITE_STATIC() -> sqlite3_destructor_type {
|
||||
None
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn SQLITE_TRANSIENT() -> sqlite3_destructor_type {
|
||||
Some(unsafe { mem::transmute::<isize, unsafe extern "C" fn(*mut std::ffi::c_void)>(-1_isize) })
|
||||
}
|
||||
|
||||
#[allow(dead_code, clippy::all)]
|
||||
mod bindings {
|
||||
include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
|
||||
}
|
||||
pub use bindings::*;
|
||||
|
||||
impl Default for sqlite3_vtab {
|
||||
fn default() -> Self {
|
||||
unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for sqlite3_vtab_cursor {
|
||||
fn default() -> Self {
|
||||
unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
echo "$SCRIPT_DIR"
|
||||
cd "$SCRIPT_DIR" || { echo "fatal error" >&2; exit 1; }
|
||||
cargo clean -p libsqlite3-sys
|
||||
TARGET_DIR="$SCRIPT_DIR/../target"
|
||||
export SQLITE3_LIB_DIR="$SCRIPT_DIR/sqlite3"
|
||||
mkdir -p "$TARGET_DIR" "$SQLITE3_LIB_DIR"
|
||||
|
||||
# Download and extract amalgamation
|
||||
SQLITE=sqlite-amalgamation-3460000
|
||||
curl -O https://sqlite.org/2024/$SQLITE.zip
|
||||
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.c" > "$SQLITE3_LIB_DIR/sqlite3.c"
|
||||
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.h" > "$SQLITE3_LIB_DIR/sqlite3.h"
|
||||
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3ext.h" > "$SQLITE3_LIB_DIR/sqlite3ext.h"
|
||||
rm -f "$SQLITE.zip"
|
||||
|
||||
export SQLITE3_INCLUDE_DIR="$SQLITE3_LIB_DIR"
|
||||
# Regenerate bindgen file for sqlite3.h
|
||||
rm -f "$SQLITE3_LIB_DIR/bindgen_bundled_version.rs"
|
||||
cargo update --quiet
|
||||
# Just to make sure there is only one bindgen.rs file in target dir
|
||||
find "$TARGET_DIR" -type f -name bindgen.rs -exec rm {} \;
|
||||
env LIBSQLITE3_SYS_BUNDLING=1 cargo build --features "buildtime_bindgen session" --no-default-features
|
||||
find "$TARGET_DIR" -type f -name bindgen.rs -exec mv {} "$SQLITE3_LIB_DIR/bindgen_bundled_version.rs" \;
|
||||
|
||||
# Regenerate bindgen file for sqlite3ext.h
|
||||
# some sqlite3_api_routines fields are function pointers with va_list arg but currently stable Rust doesn't support this type.
|
||||
# FIXME how to generate portable bindings without :
|
||||
sed -i.bk -e 's/va_list/void*/' "$SQLITE3_LIB_DIR/sqlite3ext.h"
|
||||
rm -f "$SQLITE3_LIB_DIR/bindgen_bundled_version_ext.rs"
|
||||
find "$TARGET_DIR" -type f -name bindgen.rs -exec rm {} \;
|
||||
env LIBSQLITE3_SYS_BUNDLING=1 cargo build --features "buildtime_bindgen loadable_extension" --no-default-features
|
||||
find "$TARGET_DIR" -type f -name bindgen.rs -exec mv {} "$SQLITE3_LIB_DIR/bindgen_bundled_version_ext.rs" \;
|
||||
git checkout "$SQLITE3_LIB_DIR/sqlite3ext.h"
|
||||
rm -f "$SQLITE3_LIB_DIR/sqlite3ext.h.bk"
|
||||
|
||||
# Sanity checks
|
||||
cd "$SCRIPT_DIR/.." || { echo "fatal error" >&2; exit 1; }
|
||||
cargo update --quiet
|
||||
cargo test --features "backup blob chrono functions limits load_extension serde_json trace vtab bundled"
|
||||
printf ' \e[35;1mFinished\e[0m bundled sqlite3 tests\n'
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
echo "$SCRIPT_DIR"
|
||||
cd "$SCRIPT_DIR" || { echo "fatal error" >&2; exit 1; }
|
||||
cargo clean -p libsqlite3-sys
|
||||
mkdir -p "$SCRIPT_DIR/../target" "$SCRIPT_DIR/sqlcipher"
|
||||
export SQLCIPHER_LIB_DIR="$SCRIPT_DIR/sqlcipher"
|
||||
export SQLCIPHER_INCLUDE_DIR="$SQLCIPHER_LIB_DIR"
|
||||
|
||||
SQLCIPHER_VERSION="4.5.7"
|
||||
# Download and generate sqlcipher amalgamation
|
||||
mkdir -p $SCRIPT_DIR/sqlcipher.src
|
||||
[ -e "v${SQLCIPHER_VERSION}.tar.gz" ] || curl -sfL -O "https://github.com/sqlcipher/sqlcipher/archive/v${SQLCIPHER_VERSION}.tar.gz"
|
||||
tar xzf "v${SQLCIPHER_VERSION}.tar.gz" --strip-components=1 -C "$SCRIPT_DIR/sqlcipher.src"
|
||||
cd "$SCRIPT_DIR/sqlcipher.src"
|
||||
./configure --with-crypto-lib=none
|
||||
make sqlite3.c
|
||||
cp sqlite3.c sqlite3.h sqlite3ext.h "$SCRIPT_DIR/sqlcipher/"
|
||||
cd "$SCRIPT_DIR"
|
||||
rm -rf "v${SQLCIPHER_VERSION}.tar.gz" sqlcipher.src
|
||||
|
||||
# Regenerate bindgen file for sqlcipher
|
||||
rm -f "$SQLCIPHER_LIB_DIR/bindgen_bundled_version.rs"
|
||||
|
||||
# cargo update
|
||||
find "$SCRIPT_DIR/../target" -type f -name bindgen.rs -exec rm {} \;
|
||||
env LIBSQLITE3_SYS_BUNDLING=1 cargo build --features "sqlcipher buildtime_bindgen session"
|
||||
find "$SCRIPT_DIR/../target" -type f -name bindgen.rs -exec mv {} "$SQLCIPHER_LIB_DIR/bindgen_bundled_version.rs" \;
|
||||
|
||||
# Sanity checks
|
||||
cd "$SCRIPT_DIR/.." || { echo "fatal error" >&2; exit 1; }
|
||||
cargo update --quiet
|
||||
cargo test --features "backup blob chrono functions limits load_extension serde_json trace vtab bundled-sqlcipher-vendored-openssl"
|
||||
printf ' \e[35;1mFinished\e[0m bundled-sqlcipher-vendored-openssl/sqlcipher tests\n'
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#include "sqlite3.h"
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
#include "sqlite3ext.h"
|
||||
|
||||
Reference in New Issue
Block a user