rsqlite
This library is a zero-overhead, ergonamic wrapper over sqlite C api.
// creates a database file 'dbfile.db' if it does not exists.
let database = open?;
// executes the query and creates a 'user' table
database.execute?;
// inserts a new user record.
// binds the fields to '?' .
// note that only these types are allowed for bindings:
// int32, i64, f64, &str, &[u8]
// use `&[u8]` to store blob data.
database.execute?;
let name = Stringfrom;
database.execute?;
// slects from user table on a condition ( age > 27 ),
// and executes the closure for each row returned.
database.for_each?;
// selects the count(*) from user table
// you can extract a single culumn single row result to:
// i32, i64, f64, String, Box<[u8]>
let count: i32 = database.collect?;
// you can also extract single row with multiple columns
let amin: = database.collect?;
// this also works, the returned value will be automatically converted to String
let str_count: String = database.collect?;
Additional flags
You can pass additional open flags to SQLite:
[]
= "*"
use ;
let flags = SQLITE_READONLY;
let database = open_with_flags?;
// now you can only read from the database
let n: i32 = database.collect?;
Prepared Statements
It is possible to retain and reuse statments, this will keep the query plan and might increase the performance significantly if the statement is reused.
let mut statement = database.prepare?;
// Database methods are simply implemented in terms of statements.
statement.for_each?;
let age: i32 = database.prepare?
.collect?;
NULL values
If you have NULLABLE columes, you can use Option<T> to pass and collect the values.
// use `None` to insert NULL values
database.execute?;
// use Option<T> to collect them back
let : =
database.collect?;
assert!;
// an empty result set, would also be treated as None
let name : = database.collect?;
assert!;
Type conversions
implsit type convertions in sqlite follow this table:
for example, if you collect a NULL column as i32, you'll get 0.
| Internal Type | Requested Type | Conversion |
|---|---|---|
| NULL | i32/i64 | Result is 0 |
| NULL | f64 | Result is 0.0 |
| NULL | String | Result is empty String::new() |
| NULL | Box<[u8]> | Result is empty Box::new([]) |
| INTEGER | f64 | Convert from integer to f64 |
| INTEGER | String | ASCII rendering of the integer |
| INTEGER | Box<[u8]> | Same as INTEGER->String |
| FLOAT | i32/i64 | CAST to INTEGER |
| FLOAT | String | ASCII rendering of the float |
| FLOAT | Box<[u8]> | CAST to [u8] |
| TEXT | i32/i64 | CAST to i32/i64 |
| TEXT | f64 | CAST to f64 |
| TEXT | Box<[u8]> | No change |
| BLOB | i32/i64 | CAST to i32/i64 |
| BLOB | f64 | CAST to f64 |
| BLOB | String | No change |
Transactions
You can use transactions with begin, commit and rollback commands.
database.execute?; // begin a transaction ...
let mut statement = database.prepare?;
// insert 10 users using a prepared statement
for age in 0..10
database.execute?; // commit all the changes
database.execute?; // begin another transaction ...
database.execute?;
database.execute?; // cancel this transaction
let sum_age : i32 = database.collect?;
assert!;
Blob
Use &[u8] to store and Box<[u8]> to retrive blob data.
database.execute?;
let numbers = vec!;
database.execute?;
let stored_numbers : =
database.collect?;
assert!;
License
MIT license - http://www.opensource.org/licenses/mit-license.php