Skip to content

udoprog/sqlite-ll

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sqlite-ll

github crates.io docs.rs build status

Low-level interface to the SQLite database.

This is a rewrite of the sqlite crate, and components used from there have been copied under the MIT license.


Why do we need another sqlite interface?

It is difficult to use prepared statements with existing crates, because they are all implemented in a manner which requires the caller to borrow the connection in use.

Prepared statements can be expensive to create and should be cached and re-used to achieve the best performance. This library uses sqlite3_close_v2 when the connection is dropped, causing the closing of the connection to be delayed until resources associated with it has been closed.

The way this crate gets around this is by making the prepare function unsafe, so the impetus is on the caller to ensure that the connection it's related to stays alive for the duration of the prepared statement.


Example

Open a connection, create a table, and insert some rows:

let c = sqlite_ll::Connection::open(":memory:")?;

c.execute(
    "
    CREATE TABLE users (name TEXT, age INTEGER);
    INSERT INTO users VALUES ('Alice', 42);
    INSERT INTO users VALUES ('Bob', 69);
    ",
)?;

Select some rows and process them one by one as plain text:

c.iterate("SELECT * FROM users WHERE age > 50", |pairs| {
    for &(column, value) in pairs.iter() {
        println!("{} = {}", column, value.unwrap());
    }

    true
})?;

The same query using a prepared statement, which is much more efficient than parsing and running statements ad-hoc. They must be reset before every re-use.

use sqlite_ll::State;
let mut statement = connection.prepare("SELECT * FROM users WHERE age > ?")?;

let mut results = Vec::new();

for age in [40, 50] {
    statement.reset()?;
    statement.bind(1, age)?;

    while let State::Row = statement.step()? {
        results.push((statement.read::<String>(0)?, statement.read::<i64>(1)?));
    }
}

let expected = vec![
    (String::from("Alice"), 42),
    (String::from("Bob"), 69),
    (String::from("Bob"), 69),
];

assert_eq!(results, expected);

About

Low-level interface to the SQLite crate

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages