pub struct Connection { /* private fields */ }Expand description
A handle to a SQLRite database. Opens a file or an in-memory DB;
drop it to close. Every mutating statement auto-saves (except inside
an explicit BEGIN/COMMIT block — see Transactions).
§Transactions
let mut conn = Connection::open("foo.sqlrite")?;
conn.execute("BEGIN")?;
conn.execute("INSERT INTO users (name) VALUES ('alice')")?;
conn.execute("INSERT INTO users (name) VALUES ('bob')")?;
conn.execute("COMMIT")?;Connection is Send but not Sync — clone it (it’s currently
unclonable) or share via a Mutex<Connection> if you need
multi-threaded access.
Implementations§
Source§impl Connection
impl Connection
Sourcepub fn open<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>
Opens (or creates) a database file for read-write access.
If the file doesn’t exist, an empty one is materialized with the
current format version. Takes an exclusive advisory lock on the
file and its -wal sidecar; returns Err if either is already
locked by another process.
Sourcepub fn open_read_only<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn open_read_only<P: AsRef<Path>>(path: P) -> Result<Self>
Opens an existing database file for read-only access. Takes a
shared advisory lock, so multiple read-only connections can
coexist on the same file; any open writer excludes them.
Mutating statements return cannot execute: database is opened read-only.
Sourcepub fn open_in_memory() -> Result<Self>
pub fn open_in_memory() -> Result<Self>
Opens a transient in-memory database. No file is touched and no
locks are taken; state lives for the lifetime of the
Connection and is discarded on drop.
Examples found in repository?
14fn main() -> Result<()> {
15 let mut conn = Connection::open_in_memory()?;
16
17 conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);")?;
18 conn.execute("INSERT INTO users (name, age) VALUES ('alice', 30);")?;
19 conn.execute("INSERT INTO users (name, age) VALUES ('bob', 25);")?;
20 conn.execute("INSERT INTO users (name, age) VALUES ('charlie', 40);")?;
21
22 println!("All users:");
23 let stmt = conn.prepare("SELECT id, name, age FROM users;")?;
24 let mut rows = stmt.query()?;
25 while let Some(row) = rows.next()? {
26 let id: i64 = row.get_by_name("id")?;
27 let name: String = row.get_by_name("name")?;
28 // `Option<i64>` wraps NULL cleanly — `age` is declared
29 // nullable so the typed accessor surfaces None when absent.
30 let age: Option<i64> = row.get_by_name("age")?;
31 println!(
32 " {} — {} ({})",
33 id,
34 name,
35 age.map(|a| a.to_string())
36 .unwrap_or_else(|| "NULL".to_string())
37 );
38 }
39
40 // Transactions: BEGIN + INSERT + ROLLBACK leaves the table untouched.
41 conn.execute("BEGIN;")?;
42 conn.execute("INSERT INTO users (name, age) VALUES ('will_vanish', 99);")?;
43 println!("\nMid-transaction row count: {}", count_users(&mut conn)?);
44 conn.execute("ROLLBACK;")?;
45 println!(
46 "Post-rollback row count: {} (unchanged)",
47 count_users(&mut conn)?
48 );
49
50 Ok(())
51}Sourcepub fn execute(&mut self, sql: &str) -> Result<String>
pub fn execute(&mut self, sql: &str) -> Result<String>
Parses and executes one SQL statement. For DDL (CREATE TABLE,
CREATE INDEX), DML (INSERT, UPDATE, DELETE) and
transaction control (BEGIN, COMMIT, ROLLBACK). Returns
the status message the engine produced (e.g.
"INSERT Statement executed.").
For SELECT, execute works but discards the row data and
just returns the rendered status — use Connection::prepare
and Statement::query to iterate typed rows.
Examples found in repository?
14fn main() -> Result<()> {
15 let mut conn = Connection::open_in_memory()?;
16
17 conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);")?;
18 conn.execute("INSERT INTO users (name, age) VALUES ('alice', 30);")?;
19 conn.execute("INSERT INTO users (name, age) VALUES ('bob', 25);")?;
20 conn.execute("INSERT INTO users (name, age) VALUES ('charlie', 40);")?;
21
22 println!("All users:");
23 let stmt = conn.prepare("SELECT id, name, age FROM users;")?;
24 let mut rows = stmt.query()?;
25 while let Some(row) = rows.next()? {
26 let id: i64 = row.get_by_name("id")?;
27 let name: String = row.get_by_name("name")?;
28 // `Option<i64>` wraps NULL cleanly — `age` is declared
29 // nullable so the typed accessor surfaces None when absent.
30 let age: Option<i64> = row.get_by_name("age")?;
31 println!(
32 " {} — {} ({})",
33 id,
34 name,
35 age.map(|a| a.to_string())
36 .unwrap_or_else(|| "NULL".to_string())
37 );
38 }
39
40 // Transactions: BEGIN + INSERT + ROLLBACK leaves the table untouched.
41 conn.execute("BEGIN;")?;
42 conn.execute("INSERT INTO users (name, age) VALUES ('will_vanish', 99);")?;
43 println!("\nMid-transaction row count: {}", count_users(&mut conn)?);
44 conn.execute("ROLLBACK;")?;
45 println!(
46 "Post-rollback row count: {} (unchanged)",
47 count_users(&mut conn)?
48 );
49
50 Ok(())
51}Sourcepub fn prepare<'c>(&'c mut self, sql: &str) -> Result<Statement<'c>>
pub fn prepare<'c>(&'c mut self, sql: &str) -> Result<Statement<'c>>
Prepares a statement for repeated execution or row iteration.
The SQL is parsed once and validated; the resulting
Statement can be executed multiple times. Today this is
primarily useful for SELECT (to reach the typed-row API);
parameter binding and prepared-plan caching are future work.
Examples found in repository?
14fn main() -> Result<()> {
15 let mut conn = Connection::open_in_memory()?;
16
17 conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);")?;
18 conn.execute("INSERT INTO users (name, age) VALUES ('alice', 30);")?;
19 conn.execute("INSERT INTO users (name, age) VALUES ('bob', 25);")?;
20 conn.execute("INSERT INTO users (name, age) VALUES ('charlie', 40);")?;
21
22 println!("All users:");
23 let stmt = conn.prepare("SELECT id, name, age FROM users;")?;
24 let mut rows = stmt.query()?;
25 while let Some(row) = rows.next()? {
26 let id: i64 = row.get_by_name("id")?;
27 let name: String = row.get_by_name("name")?;
28 // `Option<i64>` wraps NULL cleanly — `age` is declared
29 // nullable so the typed accessor surfaces None when absent.
30 let age: Option<i64> = row.get_by_name("age")?;
31 println!(
32 " {} — {} ({})",
33 id,
34 name,
35 age.map(|a| a.to_string())
36 .unwrap_or_else(|| "NULL".to_string())
37 );
38 }
39
40 // Transactions: BEGIN + INSERT + ROLLBACK leaves the table untouched.
41 conn.execute("BEGIN;")?;
42 conn.execute("INSERT INTO users (name, age) VALUES ('will_vanish', 99);")?;
43 println!("\nMid-transaction row count: {}", count_users(&mut conn)?);
44 conn.execute("ROLLBACK;")?;
45 println!(
46 "Post-rollback row count: {} (unchanged)",
47 count_users(&mut conn)?
48 );
49
50 Ok(())
51}
52
53fn count_users(conn: &mut Connection) -> Result<usize> {
54 let stmt = conn.prepare("SELECT id FROM users;")?;
55 let rows = stmt.query()?.collect_all()?;
56 Ok(rows.len())
57}Sourcepub fn in_transaction(&self) -> bool
pub fn in_transaction(&self) -> bool
Returns true while a BEGIN … COMMIT/ROLLBACK block is open
against this connection.
Sourcepub fn is_read_only(&self) -> bool
pub fn is_read_only(&self) -> bool
Returns true if the connection was opened read-only. Mutating
statements on a read-only connection return a typed error.