Skip to content
/ rusqlite Public
forked fromrusqlite/rusqlite

Ergonomic bindings to SQLite for Rust

License

Notifications You must be signed in to change notification settings

osohq/rusqlite

Repository files navigation

Rusqlite

Latest Version Documentation Build Status (GitHub) Build Status (AppVeyor) Code Coverage Dependency Status Discord Chat

Rusqlite is an ergonomic wrapper for using SQLite from Rust.

Historically, the API was based on the one fromrust-postgres.However, the two have diverged in many ways, and no compatibility between the two is intended.

Usage

In your Cargo.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:

userusqlite::{Connection,Result};

#[derive(Debug)]
structPerson{
id:i32,
name:String,
data:Option<Vec<u8>>,
}

fnmain()->Result<()>{
letconn =Connection::open_in_memory()?;

conn.execute(
"CREATE TABLE person (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
data BLOB
) ",
(),// empty list of parameters.
)?;
letme =Person{
id:0,
name:"Steven".to_string(),
data:None,
};
conn.execute(
"INSERT INTO person (name, data) VALUES (?1,?2)",
(&me.name,&me.data),
)?;

letmutstmt = conn.prepare("SELECT id, name, data FROM person")?;
letperson_iter = stmt.query_map([],|row|{
Ok(Person{
id:row.get(0)?,
name:row.get(1)?,
data:row.get(2)?,
})
})?;

forpersoninperson_iter{
println!("Found person {:?}",person.unwrap());
}
Ok(())
}

Supported SQLite Versions

The baserusqlitepackage 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 behindCargo features.They are:

  • load_extension allows loading dynamic library-based SQLite extensions.
  • loadable_extensionto programloadable extensionin Rust.
  • backup allows use of SQLite's online backup API.
  • functions allows you to load Rust closures into SQLite connections for use in queries.
  • windowforwindow functionsupport (fun(...) OVER...). (Impliesfunctions.)
  • trace allows hooks into SQLite's tracing and profiling APIs.
  • blob givesstd::io::{Read, Write, Seek}access to SQL BLOBs.
  • limits allows you to set and retrieve SQLite's per connection limits.
  • chronoimplementsFromSql andToSqlfor various types from thechronocrate.
  • serde_jsonimplementsFromSql andToSqlfor the Valuetype from theserde_jsoncrate.
  • timeimplementsFromSql andToSqlfor various types from thetimecrate.
  • urlimplementsFromSql andToSqlfor the Urltype from theurlcrate.
  • bundleduses a bundled version of SQLite. This is a good option for cases where linking to SQLite is complicated, such as Windows.
  • sqlcipherlooks for the SQLCipher library to link against instead of SQLite. This feature overridesbundled.
  • bundled-sqlcipheruses a bundled version of SQLCipher. This searches for and links against a system-installed crypto library to provide the crypto implementation.
  • bundled-sqlcipher-vendored-opensslallows using bundled-sqlcipher with a vendored version of OpenSSL (via theopenssl-syscrate) as the crypto provider.
    • As the name implies this depends on thebundled-sqlcipherfeature, and automatically turns it on.
    • If turned on, this uses theopenssl-syscrate, with thevendoredfeature enabled in order to build and bundle the OpenSSL crypto library.
  • hooksforCommit, RollbackandData Changenotification callbacks.
  • preupdate_hookforpreupdatenotification callbacks. (Implieshooks.)
  • unlock_notifyforUnlocknotification.
  • vtabforvirtual tablesupport (allows you to write virtual table implementations in Rust). Currently, only read-only virtual tables are supported.
  • seriesexposesgenerate_series(...)Table-Valued Function. (Impliesvtab.)
  • csvtab,CSV virtual table written in Rust. (Impliesvtab.)
  • array,Therarray()Table-Valued Function. (Impliesvtab.)
  • i128_bloballows storing values of typei128type 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.
  • uuidallows storing and retrievingUuidvalues from theuuidcrate using blobs.
  • session,Session module extension. Requiresbuildtime_bindgenfeature. (Implieshooks.)
  • extra_checkfail when a query passed to execute is readonly or has a column count > 0.
  • column_decltypeprovidescolumns()method for Statements and Rows; omit if linking to a version of SQLite/SQLCipher compiled with-DSQLITE_OMIT_DECLTYPE.
  • collationexposessqlite3_create_collation_v2.
  • serializeexposessqlite3_serialize(3.23.0).

Notes on building rusqlite and libsqlite3-sys

libsqlite3-sysis a separate crate fromrusqlitethat provides the Rust declarations for SQLite's C API. By default,libsqlite3-sysattempts to find a SQLite library that already exists on your system using pkg-config, or a Vcpkginstallation for MSVC ABI builds.

You can adjust this behavior in a number of ways:

  • If you use thebundled,bundled-sqlcipher,orbundled-sqlcipher-vendored-opensslfeatures,libsqlite3-syswill use the cccrate to compile SQLite or SQLCipher from source and link against that. This source is embedded in thelibsqlite3-syscrate and is currently SQLite 3.46.0 (as ofrusqlite0.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 yourCargo.tomlfile:

    [dependencies.rusqlite]
    version="0.32.0"
    features= ["bundled"]
  • When using any of thebundledfeatures, the build script will honorSQLITE_MAX_VARIABLE_NUMBERandSQLITE_MAX_EXPR_DEPTHvariables. It will also honor aLIBSQLITE3_FLAGSvariable, which can have a format like"-USQLITE_ALPHA -DSQLITE_BETA SQLITE_GAMMA...".That would disable theSQLITE_ALPHAflag, and set theSQLITE_BETAandSQLITE_GAMMAflags. (The initial-Dcan be omitted, as on the last one.)

  • When usingbundled-sqlcipher(and not also usingbundled-sqlcipher-vendored-openssl),libsqlite3-syswill need to link against crypto libraries on the system. If the build script can find alibcryptofrom OpenSSL or LibreSSL (it will consultOPENSSL_LIB_DIR/OPENSSL_INCLUDE_DIRandOPENSSL_DIRenvironment 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 (sonotusing any of thebundledfeatures), you can set theSQLITE3_LIB_DIR(orSQLCIPHER_LIB_DIR) environment variable to point to a directory containing the library. You can also set theSQLITE3_INCLUDE_DIR(orSQLCIPHER_INCLUDE_DIR) variable to point to the directory containingsqlite3.h.

  • Installing the sqlite3 development packages will usually be all that is required, but the build helpers forpkg-config andvcpkghave some additional configuration options. The default when using vcpkg is to dynamically link, which must be enabled by settingVCPKGRS_DYNAMIC=1environment variable before build. vcpkg install sqlite3:x64-windowswill install the required library.

  • When linking against a SQLite (or SQLCipher) library already on the system, you can set theSQLITE3_STATIC(orSQLCIPHER_STATIC) environment variable to 1 to request that the library be statically instead of dynamically linked.

Binding generation

We usebindgento generate the Rust declarations from SQLite's C header file.bindgen recommends running this as part of the build process of libraries that used this. We tried this briefly (rusqlite0.10.0, specifically), but it had some annoyances:

  • The build time forlibsqlite3-sys(and thereforerusqlite) increased dramatically.
  • Runningbindgenrequires a relatively-recent version of Clang, which many systems do not have installed by default.
  • Runningbindgenalso requires the SQLite header file to be present.

As ofrusqlite0.10.1, we avoid runningbindgenat 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-sysdirectly, 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 thebundledfeatures, 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 runbindgenat buildtime to produce your own bindings, use thebuildtime_bindgenCargo feature.

If you enable themodern_sqlitefeature, we'll use the bindings we would have included with the bundled build. You generally should havebuildtime_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-fullenables bundled and all features which don't require binding generation, and can be used instead.

Checklist

  • Runcargo fmtto ensure your Rust code is correctly formatted.
  • Ensurecargo clippy --workspace --features bundledpasses without warnings.
  • Ensurecargo clippy --workspace --features "bundled-full session buildtime_bindgen"passes without warnings.
  • Ensurecargo test --workspace --features bundledreports no failures.
  • Ensurecargo 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 /rusqlite/rusqlite/graphs/contributors

Community

Feel free to join theRusqlite Discord Serverto discuss or get help withrusqliteorlibsqlite3-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 cargofeatures,rusqlite and libsqlite3-sys will also bundle other libraries, which have their own licensing terms:

  • If--features=bundled-sqlcipheris enabled, the vendored source ofSQLcipherwill be compiled and statically linked in. SQLcipher is distributed under a BSD-style license, as describedhere.

  • If--features=bundledis enabled, the vendored source of SQLite will be compiled and linked in. SQLite is in the public domain, as describedhere.

Both of these are quite permissive, have no bearing on the license of the code inrusqliteorlibsqlite3-systhemselves, and can be entirely ignored if you do not use the feature in question.

About

Ergonomic bindings to SQLite for Rust

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Rust 99.7%
  • Other 0.3%