pub struct Connection { /* private fields */ }Expand description
A sqlite database connection.
Connections are not thread-safe objects.
§Examples
Opening a connection to a filesystem path:
use sqll::Connection;
let c = Connection::open("database.db")?;
c.execute("CREATE TABLE test (id INTEGER);")?;Opening an in-memory database:
use sqll::Connection;
let c = Connection::open_memory()?;
c.execute("CREATE TABLE test (id INTEGER);")?;Implementations§
Source§impl Connection
impl Connection
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Connection>
Available on crate feature std only.
pub fn open(path: impl AsRef<Path>) -> Result<Connection>
std only.Open a database to the given path.
Note that it is possible to open an in-memory database by passing
":memory:" here, this call might require allocating depending on the
platform, so it should be avoided in favor of using open_memory. To avoid
allocating for regular paths, you can use open_c_str, however you
are responsible for ensuring the c-string is a valid path.
This is the same as calling:
use sqll::OpenOptions;
let c = OpenOptions::new()
.extended_result_codes()
.read_write()
.create()
.open(path)?;
Sourcepub fn open_c_str(name: &CStr) -> Result<Connection>
pub fn open_c_str(name: &CStr) -> Result<Connection>
Open a database connection with a raw c-string.
This can be used to open in-memory databases by passing c":memory:" or
a regular open call with a filesystem path like
c"/path/to/database.sql".
This is the same as calling:
use sqll::OpenOptions;
let c = OpenOptions::new()
.extended_result_codes()
.read_write()
.create()
.open_c_str(name)?;
Sourcepub fn open_memory() -> Result<Connection>
pub fn open_memory() -> Result<Connection>
Open an in-memory database.
This is the same as calling
This is the same as calling:
use sqll::OpenOptions;
let c = OpenOptions::new()
.extended_result_codes()
.read_write()
.create()
.open_memory()?;
Sourcepub fn execute(&self, stmt: impl AsRef<str>) -> Result<()>
pub fn execute(&self, stmt: impl AsRef<str>) -> Result<()>
Execute a statement without processing the resulting rows if any.
Sourcepub fn set_extended_result_codes(&mut self, enabled: bool) -> Result<()>
pub fn set_extended_result_codes(&mut self, enabled: bool) -> Result<()>
Enable or disable extended result codes.
This can also be set during construction with
OpenOptions::extended_result_codes.
§Examples
use sqll::{OpenOptions, Code};
let mut c = OpenOptions::new().create().read_write().open_memory()?;
let e = c.execute("
CREATE TABLE users (name TEXT);
CREATE UNIQUE INDEX idx_users_name ON users (name);
INSERT INTO users VALUES ('Bob');
");
let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
assert_eq!(e.code(), Code::CONSTRAINT);
c.set_extended_result_codes(true)?;
let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
assert_eq!(e.code(), Code::CONSTRAINT_UNIQUE);Sourcepub fn error_message(&self) -> &str
pub fn error_message(&self) -> &str
Get the last error message for this connection.
When operating in multi-threaded environment, the error message seen here might not correspond to the query that failed unless some kind of external synchronization is in use which is the recommended way to use sqlite.
This is only meaningful if an error has occured. If no errors have
occured, this returns a non-erronous message like "not an error"
(default for sqlite3).
§Examples
use sqll::{Connection, Code};
let mut c = Connection::open_memory()?;
let e = c.execute("
CREATE TABLE users (name TEXT);
CREATE UNIQUE INDEX idx_users_name ON users (name);
INSERT INTO users VALUES ('Bob');
");
let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
assert_eq!(e.code(), Code::CONSTRAINT_UNIQUE);
assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");Sourcepub fn prepare(&self, stmt: impl AsRef<str>) -> Result<Statement>
pub fn prepare(&self, stmt: impl AsRef<str>) -> Result<Statement>
Build a prepared statement.
This is the same as calling prepare_with with Prepare::EMPTY.
The database connection will be kept open for the lifetime of this statement.
§Errors
If the prepare call contains multiple statements, it will error. To
execute multiple statements, use execute instead.
use sqll::{Connection, Code};
let c = Connection::open_memory()?;
let e = c.prepare(
"
CREATE TABLE test (id INTEGER) /* test */;
INSERT INTO test (id) VALUES (1);
"
).unwrap_err();
assert_eq!(e.code(), Code::ERROR);§Examples
use sqll::{Connection, State, Prepare};
let c = Connection::open_memory()?;
c.execute("CREATE TABLE test (id INTEGER);")?;
let mut insert_stmt = c.prepare("INSERT INTO test (id) VALUES (?);")?;
let mut query_stmt = c.prepare("SELECT id FROM test;")?;
drop(c);
insert_stmt.reset()?;
insert_stmt.bind(1, 42)?;
assert_eq!(insert_stmt.step()?, State::Done);
query_stmt.reset()?;
while let Some(row) = query_stmt.next()? {
let id = row.get::<i64>(0)?;
assert_eq!(id, 42);
}Sourcepub fn prepare_with(
&self,
stmt: impl AsRef<str>,
flags: Prepare,
) -> Result<Statement>
pub fn prepare_with( &self, stmt: impl AsRef<str>, flags: Prepare, ) -> Result<Statement>
Build a prepared statement with custom flags.
For long-running statements it is recommended that they have the
Prepare::PERSISTENT flag set.
The database connection will be kept open for the lifetime of this statement.
§Errors
If the prepare call contains multiple statements, it will error. To
execute multiple statements, use execute instead.
use sqll::{Connection, Code, Prepare};
let c = Connection::open_memory()?;
let e = c.prepare_with(
"
CREATE TABLE test (id INTEGER) /* test */;
INSERT INTO test (id) VALUES (1);
",
Prepare::PERSISTENT
).unwrap_err();
assert_eq!(e.code(), Code::ERROR);§Examples
use sqll::{Connection, State, Prepare};
let c = Connection::open_memory()?;
c.execute("CREATE TABLE test (id INTEGER);")?;
let mut insert_stmt = c.prepare_with("INSERT INTO test (id) VALUES (?);", Prepare::PERSISTENT)?;
let mut query_stmt = c.prepare_with("SELECT id FROM test;", Prepare::PERSISTENT)?;
drop(c);
/* .. */
insert_stmt.reset()?;
insert_stmt.bind(1, 42)?;
assert_eq!(insert_stmt.step()?, State::Done);
query_stmt.reset()?;
while let Some(row) = query_stmt.next()? {
let id = row.get::<i64>(0)?;
assert_eq!(id, 42);
}Sourcepub fn change_count(&self) -> usize
pub fn change_count(&self) -> usize
Return the number of rows inserted, updated, or deleted by the most recent INSERT, UPDATE, or DELETE statement.
§Examples
use sqll::Connection;
let c = Connection::open_memory()?;
c.execute("
CREATE TABLE users (name TEXT, age INTEGER);
INSERT INTO users VALUES ('Alice', 42);
INSERT INTO users VALUES ('Bob', 69);
")?;
assert_eq!(c.change_count(), 1);Sourcepub fn total_change_count(&self) -> usize
pub fn total_change_count(&self) -> usize
Return the total number of rows inserted, updated, and deleted by all INSERT, UPDATE, and DELETE statements since the connection was opened.
§Examples
use sqll::Connection;
let c = Connection::open_memory()?;
c.execute("
CREATE TABLE users (name TEXT, age INTEGER);
INSERT INTO users VALUES ('Alice', 42);
INSERT INTO users VALUES ('Bob', 69);
")?;
assert_eq!(c.total_change_count(), 2);Sourcepub fn last_insert_rowid(&self) -> c_longlong
pub fn last_insert_rowid(&self) -> c_longlong
Return the rowid of the most recent successful INSERT into a rowid table or virtual table.
§Examples
If there is no primary key, the last inserted row id is an internal identifier for the row:
use sqll::Connection;
let c = Connection::open_memory()?;
c.execute("
CREATE TABLE users (name TEXT);
INSERT INTO users VALUES ('Alice');
INSERT INTO users VALUES ('Bob');
")?;
assert_eq!(c.last_insert_rowid(), 2);
c.execute("INSERT INTO users VALUES ('Charlie')")?;
assert_eq!(c.last_insert_rowid(), 3);
let mut stmt = c.prepare("INSERT INTO users VALUES (?)")?;
stmt.bind(1, "Dave")?;
stmt.execute()?;
assert_eq!(c.last_insert_rowid(), 4);If there is a primary key, the last inserted row id corresponds to it:
use sqll::Connection;
let c = Connection::open_memory()?;
c.execute("
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users (name) VALUES ('Alice');
INSERT INTO users (name) VALUES ('Bob');
")?;
assert_eq!(c.last_insert_rowid(), 2);
c.execute("INSERT INTO users (name) VALUES ('Charlie')")?;
assert_eq!(c.last_insert_rowid(), 3);
c.execute("INSERT INTO users (name) VALUES ('Dave')")?;
assert_eq!(c.last_insert_rowid(), 4);
let mut select = c.prepare("SELECT id FROM users WHERE name = ?")?;
select.bind(1, "Dave")?;
while let Some(row) = select.next()? {
let id = row.get::<i64>(0)?;
assert_eq!(id, 4);
}
c.execute("DELETE FROM users WHERE id = 3")?;
assert_eq!(c.last_insert_rowid(), 4);
c.execute("INSERT INTO users (name) VALUES ('Charlie')")?;
assert_eq!(c.last_insert_rowid(), 5);
select.reset()?;
select.bind(1, "Charlie")?;
while let Some(row) = select.next()? {
let id = row.get::<i64>(0)?;
assert_eq!(id, 5);
}Sourcepub fn set_busy_handler<F>(&mut self, callback: F) -> Result<()>
pub fn set_busy_handler<F>(&mut self, callback: F) -> Result<()>
Set a callback for handling busy events.
The callback is triggered when the database cannot perform an operation
due to processing of some other request. If the callback returns true,
the operation will be repeated.
Sourcepub fn set_busy_timeout(&mut self, ms: c_int) -> Result<()>
pub fn set_busy_timeout(&mut self, ms: c_int) -> Result<()>
Set an implicit callback for handling busy events that tries to repeat rejected operations until a timeout expires.
Sourcepub fn remove_busy_handler(&mut self) -> Result<()>
pub fn remove_busy_handler(&mut self) -> Result<()>
Remove the callback handling busy events.
Trait Implementations§
Source§impl Drop for Connection
impl Drop for Connection
impl Send for Connection
Connection is Send.