sqlite/
lib.rs

1//! Interface to [SQLite][1].
2//!
3//! ## Example
4//!
5//! Open a connection, create a table, and insert a few rows:
6//!
7//! ```
8//! let connection = sqlite::open(":memory:").unwrap();
9//!
10//! let query = "
11//!     CREATE TABLE users (name TEXT, age INTEGER);
12//!     INSERT INTO users VALUES ('Alice', 42);
13//!     INSERT INTO users VALUES ('Bob', 69);
14//! ";
15//! connection.execute(query).unwrap();
16//! ```
17//!
18//! Select some rows and process them one by one as plain text, which is generally not efficient:
19//!
20//! ```
21//! # let connection = sqlite::open(":memory:").unwrap();
22//! # let query = "
23//! #     CREATE TABLE users (name TEXT, age INTEGER);
24//! #     INSERT INTO users VALUES ('Alice', 42);
25//! #     INSERT INTO users VALUES ('Bob', 69);
26//! # ";
27//! # connection.execute(query).unwrap();
28//! let query = "SELECT * FROM users WHERE age > 50";
29//!
30//! connection
31//!     .iterate(query, |pairs| {
32//!         for &(name, value) in pairs.iter() {
33//!             println!("{} = {}", name, value.unwrap());
34//!         }
35//!         true
36//!     })
37//!     .unwrap();
38//! ```
39//!
40//! Run the same query but using a prepared statement, which is much more efficient than the
41//! previous technique:
42//!
43//! ```
44//! use sqlite::State;
45//! # let connection = sqlite::open(":memory:").unwrap();
46//! # let query = "
47//! #     CREATE TABLE users (name TEXT, age INTEGER);
48//! #     INSERT INTO users VALUES ('Alice', 42);
49//! #     INSERT INTO users VALUES ('Bob', 69);
50//! # ";
51//! # connection.execute(query).unwrap();
52//!
53//! let query = "SELECT * FROM users WHERE age > ?";
54//! let mut statement = connection.prepare(query).unwrap();
55//! statement.bind((1, 50)).unwrap();
56//!
57//! while let Ok(State::Row) = statement.next() {
58//!     println!("name = {}", statement.read::<String, _>("name").unwrap());
59//!     println!("age = {}", statement.read::<i64, _>("age").unwrap());
60//! }
61//! ```
62//!
63//! Run the same query but using a cursor, which is iterable:
64//!
65//! ```
66//! # let connection = sqlite::open(":memory:").unwrap();
67//! # let query = "
68//! #     CREATE TABLE users (name TEXT, age INTEGER);
69//! #     INSERT INTO users VALUES ('Alice', 42);
70//! #     INSERT INTO users VALUES ('Bob', 69);
71//! # ";
72//! # connection.execute(query).unwrap();
73//!
74//! let query = "SELECT * FROM users WHERE age > ?";
75//!
76//! for row in connection
77//!     .prepare(query)
78//!     .unwrap()
79//!     .into_iter()
80//!     .bind((1, 50))
81//!     .unwrap()
82//!     .map(|row| row.unwrap())
83//! {
84//!     println!("name = {}", row.read::<&str, _>("name"));
85//!     println!("age = {}", row.read::<i64, _>("age"));
86//! }
87//! ```
88//!
89//! [1]: https://www.sqlite.org
90
91pub extern crate sqlite3_sys as ffi;
92
93macro_rules! c_str_to_str(
94    ($string:expr) => (std::str::from_utf8(std::ffi::CStr::from_ptr($string).to_bytes()));
95);
96
97macro_rules! c_str_to_string(
98    ($string:expr) => (
99        String::from_utf8_lossy(std::ffi::CStr::from_ptr($string as *const _).to_bytes())
100               .into_owned()
101    );
102);
103
104macro_rules! path_to_cstr(
105    ($path:expr) => (
106        match $path.to_str() {
107            Some(path) => {
108                match std::ffi::CString::new(path) {
109                    Ok(string) => string,
110                    _ => raise!("failed to process a path"),
111                }
112            }
113            _ => raise!("failed to process a path"),
114        }
115    );
116);
117
118macro_rules! str_to_cstr(
119    ($string:expr) => (
120        match std::ffi::CString::new($string) {
121            Ok(string) => string,
122            _ => raise!("failed to process a string"),
123        }
124    );
125);
126
127#[macro_use]
128mod error;
129mod value;
130
131mod connection;
132mod cursor;
133mod statement;
134
135pub use error::{Error, Result};
136pub use value::{Type, Value};
137
138pub use connection::{Connection, ConnectionThreadSafe, OpenFlags};
139pub use cursor::{Cursor, CursorWithOwnership, Row, RowIndex};
140pub use statement::{
141    Bindable, BindableWithIndex, ColumnIndex, ParameterIndex, ReadableWithIndex, State, Statement,
142};
143
144/// Open a read-write connection to a new or existing database.
145#[inline]
146pub fn open<T: AsRef<std::path::Path>>(path: T) -> Result<Connection> {
147    Connection::open(path)
148}
149
150/// Return the version number of SQLite.
151///
152/// For instance, the version `3.8.11.1` corresponds to the integer `3008011`.
153#[inline]
154pub fn version() -> usize {
155    unsafe { ffi::sqlite3_libversion_number() as usize }
156}