mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-27 03:51:38 +08:00
Rustfmt
This commit is contained in:
parent
4e5b64fbca
commit
08f96a678e
18
src/blob.rs
18
src/blob.rs
@ -92,7 +92,8 @@ impl Connection {
|
|||||||
if read_only { 0 } else { 1 },
|
if read_only { 0 } else { 1 },
|
||||||
&mut blob)
|
&mut blob)
|
||||||
};
|
};
|
||||||
c.decode_result(rc).map(|_| {
|
c.decode_result(rc)
|
||||||
|
.map(|_| {
|
||||||
Blob {
|
Blob {
|
||||||
conn: self,
|
conn: self,
|
||||||
blob: blob,
|
blob: blob,
|
||||||
@ -266,7 +267,8 @@ mod test {
|
|||||||
fn test_blob() {
|
fn test_blob() {
|
||||||
let (db, rowid) = db_with_test_blob().unwrap();
|
let (db, rowid) = db_with_test_blob().unwrap();
|
||||||
|
|
||||||
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false).unwrap();
|
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(4, blob.write(b"Clob").unwrap());
|
assert_eq!(4, blob.write(b"Clob").unwrap());
|
||||||
assert_eq!(6, blob.write(b"567890xxxxxx").unwrap()); // cannot write past 10
|
assert_eq!(6, blob.write(b"567890xxxxxx").unwrap()); // cannot write past 10
|
||||||
assert_eq!(0, blob.write(b"5678").unwrap()); // still cannot write past 10
|
assert_eq!(0, blob.write(b"5678").unwrap()); // still cannot write past 10
|
||||||
@ -274,7 +276,8 @@ mod test {
|
|||||||
blob.reopen(rowid).unwrap();
|
blob.reopen(rowid).unwrap();
|
||||||
blob.close().unwrap();
|
blob.close().unwrap();
|
||||||
|
|
||||||
blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, true).unwrap();
|
blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, true)
|
||||||
|
.unwrap();
|
||||||
let mut bytes = [0u8; 5];
|
let mut bytes = [0u8; 5];
|
||||||
assert_eq!(5, blob.read(&mut bytes[..]).unwrap());
|
assert_eq!(5, blob.read(&mut bytes[..]).unwrap());
|
||||||
assert_eq!(&bytes, b"Clob5");
|
assert_eq!(&bytes, b"Clob5");
|
||||||
@ -314,7 +317,8 @@ mod test {
|
|||||||
fn test_blob_in_bufreader() {
|
fn test_blob_in_bufreader() {
|
||||||
let (db, rowid) = db_with_test_blob().unwrap();
|
let (db, rowid) = db_with_test_blob().unwrap();
|
||||||
|
|
||||||
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false).unwrap();
|
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(8, blob.write(b"one\ntwo\n").unwrap());
|
assert_eq!(8, blob.write(b"one\ntwo\n").unwrap());
|
||||||
|
|
||||||
blob.reopen(rowid).unwrap();
|
blob.reopen(rowid).unwrap();
|
||||||
@ -338,7 +342,8 @@ mod test {
|
|||||||
let (db, rowid) = db_with_test_blob().unwrap();
|
let (db, rowid) = db_with_test_blob().unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false).unwrap();
|
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)
|
||||||
|
.unwrap();
|
||||||
let mut writer = BufWriter::new(blob);
|
let mut writer = BufWriter::new(blob);
|
||||||
|
|
||||||
// trying to write too much and then flush should fail
|
// trying to write too much and then flush should fail
|
||||||
@ -357,7 +362,8 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false).unwrap();
|
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)
|
||||||
|
.unwrap();
|
||||||
let mut writer = BufWriter::new(blob);
|
let mut writer = BufWriter::new(blob);
|
||||||
|
|
||||||
// trying to write_all too much should fail
|
// trying to write_all too much should fail
|
||||||
|
@ -280,7 +280,8 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_connection_close() {
|
fn test_connection_close() {
|
||||||
let conn = Connection::open_in_memory().unwrap();
|
let conn = Connection::open_in_memory().unwrap();
|
||||||
conn.prepare_cached("SELECT * FROM sqlite_master;").unwrap();
|
conn.prepare_cached("SELECT * FROM sqlite_master;")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
conn.close().expect("connection not closed");
|
conn.close().expect("connection not closed");
|
||||||
}
|
}
|
||||||
|
@ -137,18 +137,14 @@ impl error::Error for Error {
|
|||||||
match *self {
|
match *self {
|
||||||
Error::SqliteFailure(ref err, None) => err.description(),
|
Error::SqliteFailure(ref err, None) => err.description(),
|
||||||
Error::SqliteFailure(_, Some(ref s)) => s,
|
Error::SqliteFailure(_, Some(ref s)) => s,
|
||||||
Error::SqliteSingleThreadedMode => {
|
Error::SqliteSingleThreadedMode => "SQLite was compiled or configured for single-threaded use only",
|
||||||
"SQLite was compiled or configured for single-threaded use only"
|
|
||||||
}
|
|
||||||
Error::FromSqlConversionFailure(_, _, ref err) => err.description(),
|
Error::FromSqlConversionFailure(_, _, ref err) => err.description(),
|
||||||
Error::IntegralValueOutOfRange(_, _) => "integral value out of range of requested type",
|
Error::IntegralValueOutOfRange(_, _) => "integral value out of range of requested type",
|
||||||
Error::Utf8Error(ref err) => err.description(),
|
Error::Utf8Error(ref err) => err.description(),
|
||||||
Error::InvalidParameterName(_) => "invalid parameter name",
|
Error::InvalidParameterName(_) => "invalid parameter name",
|
||||||
Error::NulError(ref err) => err.description(),
|
Error::NulError(ref err) => err.description(),
|
||||||
Error::InvalidPath(_) => "invalid path",
|
Error::InvalidPath(_) => "invalid path",
|
||||||
Error::ExecuteReturnedResults => {
|
Error::ExecuteReturnedResults => "execute returned results - did you mean to call query?",
|
||||||
"execute returned results - did you mean to call query?"
|
|
||||||
}
|
|
||||||
Error::QueryReturnedNoRows => "query returned no rows",
|
Error::QueryReturnedNoRows => "query returned no rows",
|
||||||
Error::InvalidColumnIndex(_) => "invalid column index",
|
Error::InvalidColumnIndex(_) => "invalid column index",
|
||||||
Error::InvalidColumnName(_) => "invalid column name",
|
Error::InvalidColumnName(_) => "invalid column name",
|
||||||
|
@ -119,9 +119,13 @@ unsafe fn report_error(ctx: *mut sqlite3_context, err: &Error) {
|
|||||||
// if we're on the bundled version (since it's at least 3.17.0) and the normal constraint
|
// if we're on the bundled version (since it's at least 3.17.0) and the normal constraint
|
||||||
// error code if not.
|
// error code if not.
|
||||||
#[cfg(feature = "bundled")]
|
#[cfg(feature = "bundled")]
|
||||||
fn constraint_error_code() -> i32 { ffi::SQLITE_CONSTRAINT_FUNCTION }
|
fn constraint_error_code() -> i32 {
|
||||||
|
ffi::SQLITE_CONSTRAINT_FUNCTION
|
||||||
|
}
|
||||||
#[cfg(not(feature = "bundled"))]
|
#[cfg(not(feature = "bundled"))]
|
||||||
fn constraint_error_code() -> i32 { ffi::SQLITE_CONSTRAINT }
|
fn constraint_error_code() -> i32 {
|
||||||
|
ffi::SQLITE_CONSTRAINT
|
||||||
|
}
|
||||||
|
|
||||||
match *err {
|
match *err {
|
||||||
Error::SqliteFailure(ref err, ref s) => {
|
Error::SqliteFailure(ref err, ref s) => {
|
||||||
@ -154,7 +158,8 @@ impl<'a> ValueRef<'a> {
|
|||||||
let s = CStr::from_ptr(text as *const c_char);
|
let s = CStr::from_ptr(text as *const c_char);
|
||||||
|
|
||||||
// sqlite3_value_text returns UTF8 data, so our unwrap here should be fine.
|
// sqlite3_value_text returns UTF8 data, so our unwrap here should be fine.
|
||||||
let s = s.to_str().expect("sqlite3_value_text returned invalid UTF-8");
|
let s = s.to_str()
|
||||||
|
.expect("sqlite3_value_text returned invalid UTF-8");
|
||||||
ValueRef::Text(s)
|
ValueRef::Text(s)
|
||||||
}
|
}
|
||||||
ffi::SQLITE_BLOB => {
|
ffi::SQLITE_BLOB => {
|
||||||
@ -207,7 +212,10 @@ impl<'a> Context<'a> {
|
|||||||
FromSqlError::InvalidType => {
|
FromSqlError::InvalidType => {
|
||||||
Error::InvalidFunctionParameterType(idx, value.data_type())
|
Error::InvalidFunctionParameterType(idx, value.data_type())
|
||||||
}
|
}
|
||||||
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx as c_int, i),
|
FromSqlError::OutOfRange(i) => {
|
||||||
|
Error::IntegralValueOutOfRange(idx as c_int,
|
||||||
|
i)
|
||||||
|
}
|
||||||
FromSqlError::Other(err) => {
|
FromSqlError::Other(err) => {
|
||||||
Error::FromSqlConversionFailure(idx, value.data_type(), err)
|
Error::FromSqlConversionFailure(idx, value.data_type(), err)
|
||||||
}
|
}
|
||||||
@ -304,7 +312,9 @@ impl Connection {
|
|||||||
where F: FnMut(&Context) -> Result<T>,
|
where F: FnMut(&Context) -> Result<T>,
|
||||||
T: ToSql
|
T: ToSql
|
||||||
{
|
{
|
||||||
self.db.borrow_mut().create_scalar_function(fn_name, n_arg, deterministic, x_func)
|
self.db
|
||||||
|
.borrow_mut()
|
||||||
|
.create_scalar_function(fn_name, n_arg, deterministic, x_func)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attach a user-defined aggregate function to this database connection.
|
/// Attach a user-defined aggregate function to this database connection.
|
||||||
@ -720,17 +730,16 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_sum() {
|
fn test_sum() {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.create_aggregate_function("my_sum", 1, true, Sum).unwrap();
|
db.create_aggregate_function("my_sum", 1, true, Sum)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// sum should return NULL when given no columns (contrast with count below)
|
// sum should return NULL when given no columns (contrast with count below)
|
||||||
let no_result = "SELECT my_sum(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
let no_result = "SELECT my_sum(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
||||||
let result: Option<i64> = db.query_row(no_result, &[], |r| r.get(0))
|
let result: Option<i64> = db.query_row(no_result, &[], |r| r.get(0)).unwrap();
|
||||||
.unwrap();
|
|
||||||
assert!(result.is_none());
|
assert!(result.is_none());
|
||||||
|
|
||||||
let single_sum = "SELECT my_sum(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
let single_sum = "SELECT my_sum(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
||||||
let result: i64 = db.query_row(single_sum, &[], |r| r.get(0))
|
let result: i64 = db.query_row(single_sum, &[], |r| r.get(0)).unwrap();
|
||||||
.unwrap();
|
|
||||||
assert_eq!(4, result);
|
assert_eq!(4, result);
|
||||||
|
|
||||||
let dual_sum = "SELECT my_sum(i), my_sum(j) FROM (SELECT 2 AS i, 1 AS j UNION ALL SELECT \
|
let dual_sum = "SELECT my_sum(i), my_sum(j) FROM (SELECT 2 AS i, 1 AS j UNION ALL SELECT \
|
||||||
@ -743,7 +752,8 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_count() {
|
fn test_count() {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.create_aggregate_function("my_count", -1, true, Count).unwrap();
|
db.create_aggregate_function("my_count", -1, true, Count)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// count should return 0 when given no columns (contrast with sum above)
|
// count should return 0 when given no columns (contrast with sum above)
|
||||||
let no_result = "SELECT my_count(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
let no_result = "SELECT my_count(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
||||||
@ -751,8 +761,7 @@ mod test {
|
|||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
|
|
||||||
let single_sum = "SELECT my_count(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
let single_sum = "SELECT my_count(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
||||||
let result: i64 = db.query_row(single_sum, &[], |r| r.get(0))
|
let result: i64 = db.query_row(single_sum, &[], |r| r.get(0)).unwrap();
|
||||||
.unwrap();
|
|
||||||
assert_eq!(2, result);
|
assert_eq!(2, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
src/lib.rs
35
src/lib.rs
@ -295,7 +295,8 @@ impl Connection {
|
|||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the
|
||||||
/// underlying SQLite call fails.
|
/// underlying SQLite call fails.
|
||||||
pub fn execute(&self, sql: &str, params: &[&ToSql]) -> Result<c_int> {
|
pub fn execute(&self, sql: &str, params: &[&ToSql]) -> Result<c_int> {
|
||||||
self.prepare(sql).and_then(|mut stmt| stmt.execute(params))
|
self.prepare(sql)
|
||||||
|
.and_then(|mut stmt| stmt.execute(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to prepare and execute a single SQL statement with named parameter(s).
|
/// Convenience method to prepare and execute a single SQL statement with named parameter(s).
|
||||||
@ -317,7 +318,8 @@ impl Connection {
|
|||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the
|
||||||
/// underlying SQLite call fails.
|
/// underlying SQLite call fails.
|
||||||
pub fn execute_named(&self, sql: &str, params: &[(&str, &ToSql)]) -> Result<c_int> {
|
pub fn execute_named(&self, sql: &str, params: &[(&str, &ToSql)]) -> Result<c_int> {
|
||||||
self.prepare(sql).and_then(|mut stmt| stmt.execute_named(params))
|
self.prepare(sql)
|
||||||
|
.and_then(|mut stmt| stmt.execute_named(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the SQLite rowid of the most recent successful INSERT.
|
/// Get the SQLite rowid of the most recent successful INSERT.
|
||||||
@ -406,7 +408,9 @@ impl Connection {
|
|||||||
let mut stmt = try!(self.prepare(sql));
|
let mut stmt = try!(self.prepare(sql));
|
||||||
let mut rows = try!(stmt.query(params));
|
let mut rows = try!(stmt.query(params));
|
||||||
|
|
||||||
rows.get_expected_row().map_err(E::from).and_then(|r| f(&r))
|
rows.get_expected_row()
|
||||||
|
.map_err(E::from)
|
||||||
|
.and_then(|r| f(&r))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to execute a query that is expected to return a single row.
|
/// Convenience method to execute a query that is expected to return a single row.
|
||||||
@ -534,7 +538,9 @@ impl Connection {
|
|||||||
dylib_path: P,
|
dylib_path: P,
|
||||||
entry_point: Option<&str>)
|
entry_point: Option<&str>)
|
||||||
-> Result<()> {
|
-> Result<()> {
|
||||||
self.db.borrow_mut().load_extension(dylib_path.as_ref(), entry_point)
|
self.db
|
||||||
|
.borrow_mut()
|
||||||
|
.load_extension(dylib_path.as_ref(), entry_point)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get access to the underlying SQLite database connection handle.
|
/// Get access to the underlying SQLite database connection handle.
|
||||||
@ -849,7 +855,8 @@ impl InnerConnection {
|
|||||||
&mut c_stmt,
|
&mut c_stmt,
|
||||||
ptr::null_mut())
|
ptr::null_mut())
|
||||||
};
|
};
|
||||||
self.decode_result(r).map(|_| Statement::new(conn, RawStatement::new(c_stmt)))
|
self.decode_result(r)
|
||||||
|
.map(|_| Statement::new(conn, RawStatement::new(c_stmt)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn changes(&mut self) -> c_int {
|
fn changes(&mut self) -> c_int {
|
||||||
@ -999,12 +1006,15 @@ mod test {
|
|||||||
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
|
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
|
||||||
|
|
||||||
assert_eq!(1,
|
assert_eq!(1,
|
||||||
db.execute("INSERT INTO foo(x) VALUES (?)", &[&1i32]).unwrap());
|
db.execute("INSERT INTO foo(x) VALUES (?)", &[&1i32])
|
||||||
|
.unwrap());
|
||||||
assert_eq!(1,
|
assert_eq!(1,
|
||||||
db.execute("INSERT INTO foo(x) VALUES (?)", &[&2i32]).unwrap());
|
db.execute("INSERT INTO foo(x) VALUES (?)", &[&2i32])
|
||||||
|
.unwrap());
|
||||||
|
|
||||||
assert_eq!(3i32,
|
assert_eq!(3i32,
|
||||||
db.query_row::<i32, _>("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
|
db.query_row::<i32, _>("SELECT SUM(x) FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1061,7 +1071,8 @@ mod test {
|
|||||||
assert_eq!(insert_stmt.execute(&[&2i32]).unwrap(), 1);
|
assert_eq!(insert_stmt.execute(&[&2i32]).unwrap(), 1);
|
||||||
assert_eq!(insert_stmt.execute(&[&3i32]).unwrap(), 1);
|
assert_eq!(insert_stmt.execute(&[&3i32]).unwrap(), 1);
|
||||||
|
|
||||||
let mut query = db.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC").unwrap();
|
let mut query = db.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC")
|
||||||
|
.unwrap();
|
||||||
{
|
{
|
||||||
let mut rows = query.query(&[&4i32]).unwrap();
|
let mut rows = query.query(&[&4i32]).unwrap();
|
||||||
let mut v = Vec::<i32>::new();
|
let mut v = Vec::<i32>::new();
|
||||||
@ -1146,8 +1157,10 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_last_insert_rowid() {
|
fn test_last_insert_rowid() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)").unwrap();
|
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")
|
||||||
db.execute_batch("INSERT INTO foo DEFAULT VALUES").unwrap();
|
.unwrap();
|
||||||
|
db.execute_batch("INSERT INTO foo DEFAULT VALUES")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(db.last_insert_rowid(), 1);
|
assert_eq!(db.last_insert_rowid(), 1);
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ impl<'conn> LoadExtensionGuard<'conn> {
|
|||||||
/// Attempt to enable loading extensions. Loading extensions will be disabled when this
|
/// Attempt to enable loading extensions. Loading extensions will be disabled when this
|
||||||
/// guard goes out of scope. Cannot be meaningfully nested.
|
/// guard goes out of scope. Cannot be meaningfully nested.
|
||||||
pub fn new(conn: &Connection) -> Result<LoadExtensionGuard> {
|
pub fn new(conn: &Connection) -> Result<LoadExtensionGuard> {
|
||||||
conn.load_extension_enable().map(|_| LoadExtensionGuard { conn: conn })
|
conn.load_extension_enable()
|
||||||
|
.map(|_| LoadExtensionGuard { conn: conn })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
src/row.rs
33
src/row.rs
@ -28,7 +28,8 @@ impl<'stmt> Rows<'stmt> {
|
|||||||
/// "streaming iterator". For a more natural interface, consider using `query_map`
|
/// "streaming iterator". For a more natural interface, consider using `query_map`
|
||||||
/// or `query_and_then` instead, which return types that implement `Iterator`.
|
/// or `query_and_then` instead, which return types that implement `Iterator`.
|
||||||
pub fn next<'a>(&'a mut self) -> Option<Result<Row<'a, 'stmt>>> {
|
pub fn next<'a>(&'a mut self) -> Option<Result<Row<'a, 'stmt>>> {
|
||||||
self.stmt.and_then(|stmt| match stmt.step() {
|
self.stmt
|
||||||
|
.and_then(|stmt| match stmt.step() {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
Some(Ok(Row {
|
Some(Ok(Row {
|
||||||
stmt: stmt,
|
stmt: stmt,
|
||||||
@ -89,10 +90,7 @@ impl<'stmt, T, F> MappedRowsCrateImpl<'stmt, T, F> for MappedRows<'stmt, F>
|
|||||||
where F: FnMut(&Row) -> T
|
where F: FnMut(&Row) -> T
|
||||||
{
|
{
|
||||||
fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
|
fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
|
||||||
MappedRows {
|
MappedRows { rows: rows, map: f }
|
||||||
rows: rows,
|
|
||||||
map: f,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +101,9 @@ impl<'conn, T, F> Iterator for MappedRows<'conn, F>
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Result<T>> {
|
fn next(&mut self) -> Option<Result<T>> {
|
||||||
let map = &mut self.map;
|
let map = &mut self.map;
|
||||||
self.rows.next().map(|row_result| row_result.map(|row| (map)(&row)))
|
self.rows
|
||||||
|
.next()
|
||||||
|
.map(|row_result| row_result.map(|row| (map)(&row)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,10 +124,7 @@ impl<'stmt, T, E, F> AndThenRowsCrateImpl<'stmt, T, E, F> for AndThenRows<'stmt,
|
|||||||
where F: FnMut(&Row) -> result::Result<T, E>
|
where F: FnMut(&Row) -> result::Result<T, E>
|
||||||
{
|
{
|
||||||
fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
|
fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
|
||||||
AndThenRows {
|
AndThenRows { rows: rows, map: f }
|
||||||
rows: rows,
|
|
||||||
map: f,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +136,9 @@ impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let map = &mut self.map;
|
let map = &mut self.map;
|
||||||
self.rows.next().map(|row_result| {
|
self.rows
|
||||||
row_result.map_err(E::from)
|
.next()
|
||||||
.and_then(|row| (map)(&row))
|
.map(|row_result| row_result.map_err(E::from).and_then(|row| (map)(&row)))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,8 +178,13 @@ impl<'a, 'stmt> Row<'a, 'stmt> {
|
|||||||
let idx = try!(idx.idx(self.stmt));
|
let idx = try!(idx.idx(self.stmt));
|
||||||
let value = self.stmt.value_ref(idx);
|
let value = self.stmt.value_ref(idx);
|
||||||
FromSql::column_result(value).map_err(|err| match err {
|
FromSql::column_result(value).map_err(|err| match err {
|
||||||
FromSqlError::InvalidType => Error::InvalidColumnType(idx, value.data_type()),
|
FromSqlError::InvalidType => {
|
||||||
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
|
Error::InvalidColumnType(idx,
|
||||||
|
value.data_type())
|
||||||
|
}
|
||||||
|
FromSqlError::OutOfRange(i) => {
|
||||||
|
Error::IntegralValueOutOfRange(idx, i)
|
||||||
|
}
|
||||||
FromSqlError::Other(err) => {
|
FromSqlError::Other(err) => {
|
||||||
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
|
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
|
||||||
}
|
}
|
||||||
|
@ -405,10 +405,15 @@ impl<'conn> Statement<'conn> {
|
|||||||
.decode_result(unsafe { ffi::sqlite3_bind_zeroblob(ptr, col, len) });
|
.decode_result(unsafe { ffi::sqlite3_bind_zeroblob(ptr, col, len) });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.conn.decode_result(match value {
|
self.conn
|
||||||
|
.decode_result(match value {
|
||||||
ValueRef::Null => unsafe { ffi::sqlite3_bind_null(ptr, col) },
|
ValueRef::Null => unsafe { ffi::sqlite3_bind_null(ptr, col) },
|
||||||
ValueRef::Integer(i) => unsafe { ffi::sqlite3_bind_int64(ptr, col, i) },
|
ValueRef::Integer(i) => unsafe {
|
||||||
ValueRef::Real(r) => unsafe { ffi::sqlite3_bind_double(ptr, col, r) },
|
ffi::sqlite3_bind_int64(ptr, col, i)
|
||||||
|
},
|
||||||
|
ValueRef::Real(r) => unsafe {
|
||||||
|
ffi::sqlite3_bind_double(ptr, col, r)
|
||||||
|
},
|
||||||
ValueRef::Text(s) => unsafe {
|
ValueRef::Text(s) => unsafe {
|
||||||
let length = s.len();
|
let length = s.len();
|
||||||
if length > ::std::i32::MAX as usize {
|
if length > ::std::i32::MAX as usize {
|
||||||
@ -524,7 +529,8 @@ impl<'conn> StatementCrateImpl<'conn> for Statement<'conn> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// sqlite3_column_text returns UTF8 data, so our unwrap here should be fine.
|
// sqlite3_column_text returns UTF8 data, so our unwrap here should be fine.
|
||||||
let s = s.to_str().expect("sqlite3_column_text returned invalid UTF-8");
|
let s = s.to_str()
|
||||||
|
.expect("sqlite3_column_text returned invalid UTF-8");
|
||||||
ValueRef::Text(s)
|
ValueRef::Text(s)
|
||||||
}
|
}
|
||||||
ffi::SQLITE_BLOB => {
|
ffi::SQLITE_BLOB => {
|
||||||
@ -570,9 +576,11 @@ mod test {
|
|||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
|
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
|
||||||
|
|
||||||
assert_eq!(db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)]).unwrap(),
|
assert_eq!(db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)])
|
||||||
|
.unwrap(),
|
||||||
1);
|
1);
|
||||||
assert_eq!(db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)]).unwrap(),
|
assert_eq!(db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)])
|
||||||
|
.unwrap(),
|
||||||
1);
|
1);
|
||||||
|
|
||||||
assert_eq!(3i32,
|
assert_eq!(3i32,
|
||||||
@ -589,7 +597,8 @@ mod test {
|
|||||||
INTEGER)";
|
INTEGER)";
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("INSERT INTO test (name) VALUES (:name)").unwrap();
|
let mut stmt = db.prepare("INSERT INTO test (name) VALUES (:name)")
|
||||||
|
.unwrap();
|
||||||
stmt.execute_named(&[(":name", &"one")]).unwrap();
|
stmt.execute_named(&[(":name", &"one")]).unwrap();
|
||||||
|
|
||||||
assert_eq!(1i32,
|
assert_eq!(1i32,
|
||||||
@ -608,7 +617,8 @@ mod test {
|
|||||||
"#;
|
"#;
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("SELECT id FROM test where name = :name").unwrap();
|
let mut stmt = db.prepare("SELECT id FROM test where name = :name")
|
||||||
|
.unwrap();
|
||||||
let mut rows = stmt.query_named(&[(":name", &"one")]).unwrap();
|
let mut rows = stmt.query_named(&[(":name", &"one")]).unwrap();
|
||||||
|
|
||||||
let id: i32 = rows.next().unwrap().unwrap().get(0);
|
let id: i32 = rows.next().unwrap().unwrap().get(0);
|
||||||
@ -624,7 +634,8 @@ mod test {
|
|||||||
"#;
|
"#;
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("SELECT id FROM test where name = :name").unwrap();
|
let mut stmt = db.prepare("SELECT id FROM test where name = :name")
|
||||||
|
.unwrap();
|
||||||
let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| {
|
let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| {
|
||||||
let id: i32 = row.get(0);
|
let id: i32 = row.get(0);
|
||||||
2 * id
|
2 * id
|
||||||
@ -676,7 +687,8 @@ mod test {
|
|||||||
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
|
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)").unwrap();
|
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")
|
||||||
|
.unwrap();
|
||||||
stmt.execute_named(&[(":x", &"one")]).unwrap();
|
stmt.execute_named(&[(":x", &"one")]).unwrap();
|
||||||
|
|
||||||
let result: Option<String> =
|
let result: Option<String> =
|
||||||
@ -691,7 +703,8 @@ mod test {
|
|||||||
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
|
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)").unwrap();
|
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")
|
||||||
|
.unwrap();
|
||||||
stmt.execute_named(&[(":x", &"one")]).unwrap();
|
stmt.execute_named(&[(":x", &"one")]).unwrap();
|
||||||
stmt.execute_named(&[(":y", &"two")]).unwrap();
|
stmt.execute_named(&[(":y", &"two")]).unwrap();
|
||||||
|
|
||||||
@ -704,15 +717,18 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_insert() {
|
fn test_insert() {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)").unwrap();
|
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")
|
||||||
let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)").unwrap();
|
.unwrap();
|
||||||
|
let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")
|
||||||
|
.unwrap();
|
||||||
assert_eq!(stmt.insert(&[&1i32]).unwrap(), 1);
|
assert_eq!(stmt.insert(&[&1i32]).unwrap(), 1);
|
||||||
assert_eq!(stmt.insert(&[&2i32]).unwrap(), 2);
|
assert_eq!(stmt.insert(&[&2i32]).unwrap(), 2);
|
||||||
match stmt.insert(&[&1i32]).unwrap_err() {
|
match stmt.insert(&[&1i32]).unwrap_err() {
|
||||||
Error::StatementChangedRows(0) => (),
|
Error::StatementChangedRows(0) => (),
|
||||||
err => panic!("Unexpected error {}", err),
|
err => panic!("Unexpected error {}", err),
|
||||||
}
|
}
|
||||||
let mut multi = db.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4").unwrap();
|
let mut multi = db.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4")
|
||||||
|
.unwrap();
|
||||||
match multi.insert(&[]).unwrap_err() {
|
match multi.insert(&[]).unwrap_err() {
|
||||||
Error::StatementChangedRows(2) => (),
|
Error::StatementChangedRows(2) => (),
|
||||||
err => panic!("Unexpected error {}", err),
|
err => panic!("Unexpected error {}", err),
|
||||||
@ -729,9 +745,15 @@ mod test {
|
|||||||
")
|
")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(db.prepare("INSERT INTO foo VALUES (10)").unwrap().insert(&[]).unwrap(),
|
assert_eq!(db.prepare("INSERT INTO foo VALUES (10)")
|
||||||
|
.unwrap()
|
||||||
|
.insert(&[])
|
||||||
|
.unwrap(),
|
||||||
1);
|
1);
|
||||||
assert_eq!(db.prepare("INSERT INTO bar VALUES (10)").unwrap().insert(&[]).unwrap(),
|
assert_eq!(db.prepare("INSERT INTO bar VALUES (10)")
|
||||||
|
.unwrap()
|
||||||
|
.insert(&[])
|
||||||
|
.unwrap(),
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ impl<'conn> Transaction<'conn> {
|
|||||||
TransactionBehavior::Immediate => "BEGIN IMMEDIATE",
|
TransactionBehavior::Immediate => "BEGIN IMMEDIATE",
|
||||||
TransactionBehavior::Exclusive => "BEGIN EXCLUSIVE",
|
TransactionBehavior::Exclusive => "BEGIN EXCLUSIVE",
|
||||||
};
|
};
|
||||||
conn.execute_batch(query).map(move |_| {
|
conn.execute_batch(query)
|
||||||
|
.map(move |_| {
|
||||||
Transaction {
|
Transaction {
|
||||||
conn: conn,
|
conn: conn,
|
||||||
drop_behavior: DropBehavior::Rollback,
|
drop_behavior: DropBehavior::Rollback,
|
||||||
@ -216,7 +217,8 @@ impl<'conn> Savepoint<'conn> {
|
|||||||
name: T)
|
name: T)
|
||||||
-> Result<Savepoint> {
|
-> Result<Savepoint> {
|
||||||
let name = name.into();
|
let name = name.into();
|
||||||
conn.execute_batch(&format!("SAVEPOINT {}", name)).map(|_| {
|
conn.execute_batch(&format!("SAVEPOINT {}", name))
|
||||||
|
.map(|_| {
|
||||||
Savepoint {
|
Savepoint {
|
||||||
conn: conn,
|
conn: conn,
|
||||||
name: name,
|
name: name,
|
||||||
@ -269,7 +271,8 @@ impl<'conn> Savepoint<'conn> {
|
|||||||
|
|
||||||
fn commit_(&mut self) -> Result<()> {
|
fn commit_(&mut self) -> Result<()> {
|
||||||
self.committed = true;
|
self.committed = true;
|
||||||
self.conn.execute_batch(&format!("RELEASE {}", self.name))
|
self.conn
|
||||||
|
.execute_batch(&format!("RELEASE {}", self.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience method which rolls back a savepoint.
|
/// A convenience method which rolls back a savepoint.
|
||||||
@ -279,7 +282,8 @@ impl<'conn> Savepoint<'conn> {
|
|||||||
/// Unlike `Transaction`s, savepoints remain active after they have been rolled back,
|
/// Unlike `Transaction`s, savepoints remain active after they have been rolled back,
|
||||||
/// and can be rolled back again or committed.
|
/// and can be rolled back again or committed.
|
||||||
pub fn rollback(&mut self) -> Result<()> {
|
pub fn rollback(&mut self) -> Result<()> {
|
||||||
self.conn.execute_batch(&format!("ROLLBACK TO {}", self.name))
|
self.conn
|
||||||
|
.execute_batch(&format!("ROLLBACK TO {}", self.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes the savepoint, committing or rolling back according to the current setting
|
/// Consumes the savepoint, committing or rolling back according to the current setting
|
||||||
@ -549,7 +553,8 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn assert_current_sum(x: i32, conn: &Connection) {
|
fn assert_current_sum(x: i32, conn: &Connection) {
|
||||||
let i = conn.query_row::<i32, _>("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap();
|
let i = conn.query_row::<i32, _>("SELECT SUM(x) FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(x, i);
|
assert_eq!(x, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ impl ToSql for NaiveDate {
|
|||||||
/// "YYYY-MM-DD" => ISO 8601 calendar date without timezone.
|
/// "YYYY-MM-DD" => ISO 8601 calendar date without timezone.
|
||||||
impl FromSql for NaiveDate {
|
impl FromSql for NaiveDate {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| match NaiveDate::parse_from_str(s, "%Y-%m-%d") {
|
value
|
||||||
|
.as_str()
|
||||||
|
.and_then(|s| match NaiveDate::parse_from_str(s, "%Y-%m-%d") {
|
||||||
Ok(dt) => Ok(dt),
|
Ok(dt) => Ok(dt),
|
||||||
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
||||||
})
|
})
|
||||||
@ -37,7 +39,9 @@ impl ToSql for NaiveTime {
|
|||||||
/// "HH:MM"/"HH:MM:SS"/"HH:MM:SS.SSS" => ISO 8601 time without timezone.
|
/// "HH:MM"/"HH:MM:SS"/"HH:MM:SS.SSS" => ISO 8601 time without timezone.
|
||||||
impl FromSql for NaiveTime {
|
impl FromSql for NaiveTime {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| {
|
value
|
||||||
|
.as_str()
|
||||||
|
.and_then(|s| {
|
||||||
let fmt = match s.len() {
|
let fmt = match s.len() {
|
||||||
5 => "%H:%M",
|
5 => "%H:%M",
|
||||||
8 => "%H:%M:%S",
|
8 => "%H:%M:%S",
|
||||||
@ -63,7 +67,9 @@ impl ToSql for NaiveDateTime {
|
|||||||
/// without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS" also supported)
|
/// without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS" also supported)
|
||||||
impl FromSql for NaiveDateTime {
|
impl FromSql for NaiveDateTime {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| {
|
value
|
||||||
|
.as_str()
|
||||||
|
.and_then(|s| {
|
||||||
let fmt = if s.len() >= 11 && s.as_bytes()[10] == b'T' {
|
let fmt = if s.len() >= 11 && s.as_bytes()[10] == b'T' {
|
||||||
"%Y-%m-%dT%H:%M:%S%.f"
|
"%Y-%m-%dT%H:%M:%S%.f"
|
||||||
} else {
|
} else {
|
||||||
@ -130,7 +136,8 @@ mod test {
|
|||||||
|
|
||||||
fn checked_memory_handle() -> Connection {
|
fn checked_memory_handle() -> Connection {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT, b BLOB)").unwrap();
|
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT, b BLOB)")
|
||||||
|
.unwrap();
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,11 +145,14 @@ mod test {
|
|||||||
fn test_naive_date() {
|
fn test_naive_date() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
let date = NaiveDate::from_ymd(2016, 2, 23);
|
let date = NaiveDate::from_ymd(2016, 2, 23);
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", &[&date]).unwrap();
|
db.execute("INSERT INTO foo (t) VALUES (?)", &[&date])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!("2016-02-23", s);
|
assert_eq!("2016-02-23", s);
|
||||||
let t: NaiveDate = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let t: NaiveDate = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(date, t);
|
assert_eq!(date, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,11 +160,14 @@ mod test {
|
|||||||
fn test_naive_time() {
|
fn test_naive_time() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
let time = NaiveTime::from_hms(23, 56, 4);
|
let time = NaiveTime::from_hms(23, 56, 4);
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", &[&time]).unwrap();
|
db.execute("INSERT INTO foo (t) VALUES (?)", &[&time])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!("23:56:04", s);
|
assert_eq!("23:56:04", s);
|
||||||
let v: NaiveTime = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let v: NaiveTime = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(time, v);
|
assert_eq!(time, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,15 +178,20 @@ mod test {
|
|||||||
let time = NaiveTime::from_hms(23, 56, 4);
|
let time = NaiveTime::from_hms(23, 56, 4);
|
||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", &[&dt]).unwrap();
|
db.execute("INSERT INTO foo (t) VALUES (?)", &[&dt])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!("2016-02-23T23:56:04", s);
|
assert_eq!("2016-02-23T23:56:04", s);
|
||||||
let v: NaiveDateTime = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let v: NaiveDateTime = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(dt, v);
|
assert_eq!(dt, v);
|
||||||
|
|
||||||
db.execute("UPDATE foo set b = datetime(t)", &[]).unwrap(); // "YYYY-MM-DD HH:MM:SS"
|
db.execute("UPDATE foo set b = datetime(t)", &[])
|
||||||
let hms: NaiveDateTime = db.query_row("SELECT b FROM foo", &[], |r| r.get(0)).unwrap();
|
.unwrap(); // "YYYY-MM-DD HH:MM:SS"
|
||||||
|
let hms: NaiveDateTime = db.query_row("SELECT b FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(dt, hms);
|
assert_eq!(dt, hms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,12 +203,15 @@ mod test {
|
|||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
let utc = UTC.from_utc_datetime(&dt);
|
let utc = UTC.from_utc_datetime(&dt);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", &[&utc]).unwrap();
|
db.execute("INSERT INTO foo (t) VALUES (?)", &[&utc])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!("2016-02-23T23:56:04.789+00:00", s);
|
assert_eq!("2016-02-23T23:56:04.789+00:00", s);
|
||||||
|
|
||||||
let v1: DateTime<UTC> = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let v1: DateTime<UTC> = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(utc, v1);
|
assert_eq!(utc, v1);
|
||||||
|
|
||||||
let v2: DateTime<UTC> = db.query_row("SELECT '2016-02-23 23:56:04.789'", &[], |r| r.get(0))
|
let v2: DateTime<UTC> = db.query_row("SELECT '2016-02-23 23:56:04.789'", &[], |r| r.get(0))
|
||||||
@ -202,7 +223,8 @@ mod test {
|
|||||||
assert_eq!(utc - Duration::milliseconds(789), v3);
|
assert_eq!(utc - Duration::milliseconds(789), v3);
|
||||||
|
|
||||||
let v4: DateTime<UTC> =
|
let v4: DateTime<UTC> =
|
||||||
db.query_row("SELECT '2016-02-23 23:56:04.789+00:00'", &[], |r| r.get(0)).unwrap();
|
db.query_row("SELECT '2016-02-23 23:56:04.789+00:00'", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(utc, v4);
|
assert_eq!(utc, v4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,13 +236,16 @@ mod test {
|
|||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
let local = Local.from_local_datetime(&dt).single().unwrap();
|
let local = Local.from_local_datetime(&dt).single().unwrap();
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", &[&local]).unwrap();
|
db.execute("INSERT INTO foo (t) VALUES (?)", &[&local])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Stored string should be in UTC
|
// Stored string should be in UTC
|
||||||
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let s: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert!(s.ends_with("+00:00"));
|
assert!(s.ends_with("+00:00"));
|
||||||
|
|
||||||
let v: DateTime<Local> = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let v: DateTime<Local> = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(local, v);
|
assert_eq!(local, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,9 @@ mod test {
|
|||||||
}
|
}
|
||||||
for n in in_range {
|
for n in in_range {
|
||||||
assert_eq!(*n,
|
assert_eq!(*n,
|
||||||
db.query_row("SELECT ?", &[n], |r| r.get::<_, T>(0)).unwrap().into());
|
db.query_row("SELECT ?", &[n], |r| r.get::<_, T>(0))
|
||||||
|
.unwrap()
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,8 @@ mod test {
|
|||||||
|
|
||||||
fn checked_memory_handle() -> Connection {
|
fn checked_memory_handle() -> Connection {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo (b BLOB, t TEXT, i INTEGER, f FLOAT, n)").unwrap();
|
db.execute_batch("CREATE TABLE foo (b BLOB, t TEXT, i INTEGER, f FLOAT, n)")
|
||||||
|
.unwrap();
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,9 +129,11 @@ mod test {
|
|||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
let v1234 = vec![1u8, 2, 3, 4];
|
let v1234 = vec![1u8, 2, 3, 4];
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", &[&v1234]).unwrap();
|
db.execute("INSERT INTO foo(b) VALUES (?)", &[&v1234])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let v: Vec<u8> = db.query_row("SELECT b FROM foo", &[], |r| r.get(0)).unwrap();
|
let v: Vec<u8> = db.query_row("SELECT b FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(v, v1234);
|
assert_eq!(v, v1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +142,11 @@ mod test {
|
|||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
let empty = vec![];
|
let empty = vec![];
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", &[&empty]).unwrap();
|
db.execute("INSERT INTO foo(b) VALUES (?)", &[&empty])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let v: Vec<u8> = db.query_row("SELECT b FROM foo", &[], |r| r.get(0)).unwrap();
|
let v: Vec<u8> = db.query_row("SELECT b FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(v, empty);
|
assert_eq!(v, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,9 +155,11 @@ mod test {
|
|||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
let s = "hello, world!";
|
let s = "hello, world!";
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s]).unwrap();
|
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let from: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let from: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(from, s);
|
assert_eq!(from, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,9 +168,11 @@ mod test {
|
|||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
let s = "hello, world!";
|
let s = "hello, world!";
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s.to_owned()]).unwrap();
|
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s.to_owned()])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let from: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let from: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(from, s);
|
assert_eq!(from, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,10 +180,12 @@ mod test {
|
|||||||
fn test_value() {
|
fn test_value() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
db.execute("INSERT INTO foo(i) VALUES (?)", &[&Value::Integer(10)]).unwrap();
|
db.execute("INSERT INTO foo(i) VALUES (?)", &[&Value::Integer(10)])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(10i64,
|
assert_eq!(10i64,
|
||||||
db.query_row::<i64, _>("SELECT i FROM foo", &[], |r| r.get(0)).unwrap());
|
db.query_row::<i64, _>("SELECT i FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -184,10 +195,13 @@ mod test {
|
|||||||
let s = Some("hello, world!");
|
let s = Some("hello, world!");
|
||||||
let b = Some(vec![1u8, 2, 3, 4]);
|
let b = Some(vec![1u8, 2, 3, 4]);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s]).unwrap();
|
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s])
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", &[&b]).unwrap();
|
.unwrap();
|
||||||
|
db.execute("INSERT INTO foo(b) VALUES (?)", &[&b])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut stmt = db.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC").unwrap();
|
let mut stmt = db.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC")
|
||||||
|
.unwrap();
|
||||||
let mut rows = stmt.query(&[]).unwrap();
|
let mut rows = stmt.query(&[]).unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -232,9 +246,15 @@ mod test {
|
|||||||
assert_eq!("text", row.get_checked::<i32, String>(1).unwrap());
|
assert_eq!("text", row.get_checked::<i32, String>(1).unwrap());
|
||||||
assert_eq!(1, row.get_checked::<i32, c_int>(2).unwrap());
|
assert_eq!(1, row.get_checked::<i32, c_int>(2).unwrap());
|
||||||
assert!((1.5 - row.get_checked::<i32, c_double>(3).unwrap()).abs() < EPSILON);
|
assert!((1.5 - row.get_checked::<i32, c_double>(3).unwrap()).abs() < EPSILON);
|
||||||
assert!(row.get_checked::<i32, Option<c_int>>(4).unwrap().is_none());
|
assert!(row.get_checked::<i32, Option<c_int>>(4)
|
||||||
assert!(row.get_checked::<i32, Option<c_double>>(4).unwrap().is_none());
|
.unwrap()
|
||||||
assert!(row.get_checked::<i32, Option<String>>(4).unwrap().is_none());
|
.is_none());
|
||||||
|
assert!(row.get_checked::<i32, Option<c_double>>(4)
|
||||||
|
.unwrap()
|
||||||
|
.is_none());
|
||||||
|
assert!(row.get_checked::<i32, Option<String>>(4)
|
||||||
|
.unwrap()
|
||||||
|
.is_none());
|
||||||
|
|
||||||
// check some invalid types
|
// check some invalid types
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ mod test {
|
|||||||
|
|
||||||
fn checked_memory_handle() -> Connection {
|
fn checked_memory_handle() -> Connection {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)").unwrap();
|
db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")
|
||||||
|
.unwrap();
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,9 +47,11 @@ mod test {
|
|||||||
&[&data, &json.as_bytes()])
|
&[&data, &json.as_bytes()])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let t: serde_json::Value = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let t: serde_json::Value = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(data, t);
|
assert_eq!(data, t);
|
||||||
let b: serde_json::Value = db.query_row("SELECT b FROM foo", &[], |r| r.get(0)).unwrap();
|
let b: serde_json::Value = db.query_row("SELECT b FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(data, b);
|
assert_eq!(data, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,19 @@ const SQLITE_DATETIME_FMT: &'static str = "%Y-%m-%d %H:%M:%S";
|
|||||||
|
|
||||||
impl ToSql for time::Timespec {
|
impl ToSql for time::Timespec {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput> {
|
||||||
let time_string = time::at_utc(*self).strftime(SQLITE_DATETIME_FMT).unwrap().to_string();
|
let time_string = time::at_utc(*self)
|
||||||
|
.strftime(SQLITE_DATETIME_FMT)
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
Ok(ToSqlOutput::from(time_string))
|
Ok(ToSqlOutput::from(time_string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for time::Timespec {
|
impl FromSql for time::Timespec {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| match time::strptime(s, SQLITE_DATETIME_FMT) {
|
value
|
||||||
|
.as_str()
|
||||||
|
.and_then(|s| match time::strptime(s, SQLITE_DATETIME_FMT) {
|
||||||
Ok(tm) => Ok(tm.to_timespec()),
|
Ok(tm) => Ok(tm.to_timespec()),
|
||||||
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
||||||
})
|
})
|
||||||
@ -28,7 +33,8 @@ mod test {
|
|||||||
|
|
||||||
fn checked_memory_handle() -> Connection {
|
fn checked_memory_handle() -> Connection {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)").unwrap();
|
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)")
|
||||||
|
.unwrap();
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,9 +46,11 @@ mod test {
|
|||||||
sec: 10_000,
|
sec: 10_000,
|
||||||
nsec: 0,
|
nsec: 0,
|
||||||
};
|
};
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts]).unwrap();
|
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let from: time::Timespec = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
|
let from: time::Timespec = db.query_row("SELECT t FROM foo", &[], |r| r.get(0))
|
||||||
|
.unwrap();
|
||||||
assert_eq!(from, ts);
|
assert_eq!(from, ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,5 +13,6 @@ pub fn version_number() -> i32 {
|
|||||||
/// See [sqlite3_libversion()](https://www.sqlite.org/c3ref/libversion.html).
|
/// See [sqlite3_libversion()](https://www.sqlite.org/c3ref/libversion.html).
|
||||||
pub fn version() -> &'static str {
|
pub fn version() -> &'static str {
|
||||||
let cstr = unsafe { CStr::from_ptr(ffi::sqlite3_libversion()) };
|
let cstr = unsafe { CStr::from_ptr(ffi::sqlite3_libversion()) };
|
||||||
cstr.to_str().expect("SQLite version string is not valid UTF8 ?!")
|
cstr.to_str()
|
||||||
|
.expect("SQLite version string is not valid UTF8 ?!")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user