From cc8a68ca834d014f8b664aea3aecf18ad917c09d Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 20:39:59 -0600 Subject: [PATCH 1/7] Update for int/uint -> isize/usize --- src/ffi/mod.rs | 2 +- src/lib.rs | 12 ++++++------ src/types.rs | 10 ++++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 3a39c47..62213a9 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -42,7 +42,7 @@ pub const SQLITE_NULL : c_int = 5; pub type SqliteDestructor = extern "C" fn(*mut c_void); pub fn SQLITE_TRANSIENT() -> SqliteDestructor { - unsafe { mem::transmute(-1i) } + unsafe { mem::transmute(-1is) } } pub fn code_to_str(code: c_int) -> &'static str { diff --git a/src/lib.rs b/src/lib.rs index a1bf52a..41ab875 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,7 +210,7 @@ impl SqliteConnection { /// } /// } /// ``` - pub fn execute(&self, sql: &str, params: &[&ToSql]) -> SqliteResult { + pub fn execute(&self, sql: &str, params: &[&ToSql]) -> SqliteResult { self.prepare(sql).and_then(|mut stmt| stmt.execute(params)) } @@ -280,7 +280,7 @@ impl SqliteConnection { self.db.borrow_mut().decode_result(code) } - fn changes(&self) -> uint { + fn changes(&self) -> c_int { self.db.borrow_mut().changes() } } @@ -390,8 +390,8 @@ impl InnerSqliteConnection { }) } - fn changes(&mut self) -> uint { - unsafe{ ffi::sqlite3_changes(self.db) as uint } + fn changes(&mut self) -> c_int { + unsafe{ ffi::sqlite3_changes(self.db) } } } @@ -432,7 +432,7 @@ impl<'conn> SqliteStatement<'conn> { /// Ok(()) /// } /// ``` - pub fn execute(&mut self, params: &[&ToSql]) -> SqliteResult { + pub fn execute(&mut self, params: &[&ToSql]) -> SqliteResult { self.reset_if_needed(); unsafe { @@ -796,7 +796,7 @@ mod test { assert_eq!(db.last_insert_rowid(), 1); let mut stmt = db.prepare("INSERT INTO foo DEFAULT VALUES").unwrap(); - for _ in range(0i, 9) { + for _ in range(0i32, 9) { stmt.execute(&[]).unwrap(); } assert_eq!(db.last_insert_rowid(), 10); diff --git a/src/types.rs b/src/types.rs index c4cbe47..b63c03a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -136,9 +136,15 @@ impl ToSql for Option { /// ## Example /// /// ```rust,no_run +/// #![allow(unstable)] +/// # extern crate libc; +/// # extern crate rusqlite; /// # use rusqlite::{SqliteConnection, SqliteResult}; /// # use rusqlite::types::{Null}; -/// fn insert_null(conn: &SqliteConnection) -> SqliteResult { +/// # use libc::{c_int}; +/// fn main() { +/// } +/// fn insert_null(conn: &SqliteConnection) -> SqliteResult { /// conn.execute("INSERT INTO people (name) VALUES (?)", &[&Null]) /// } /// ``` @@ -186,7 +192,7 @@ impl FromSql for Vec { let c_blob = ffi::sqlite3_column_blob(stmt, col); let len = ffi::sqlite3_column_bytes(stmt, col); - assert!(len >= 0); let len = len as uint; + assert!(len >= 0); let len = len as usize; Ok(Vec::from_raw_buf(mem::transmute(c_blob), len)) } From 8843d15a07f0dd921af4d2264c630e18a1fac785 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 20:43:39 -0600 Subject: [PATCH 2/7] Use new Show interpolation --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 41ab875..161c36f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ //! time_created: row.get(2), //! data: row.get(3) //! }; -//! println!("Found person {}", person); +//! println!("Found person {:?}", person); //! } //! } //! ``` @@ -511,7 +511,7 @@ impl<'conn> SqliteStatement<'conn> { impl<'conn> fmt::Show for SqliteStatement<'conn> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Statement( conn: {}, stmt: {} )", self.conn, self.stmt) + write!(f, "Statement( conn: {:?}, stmt: {:?} )", self.conn, self.stmt) } } From 680056b3514776a911611e698d770e434d6d298b Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 20:50:03 -0600 Subject: [PATCH 3/7] Implement fmt::String for SqliteError --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 161c36f..e9d6037 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,6 +96,12 @@ pub struct SqliteError { pub message: String, } +impl fmt::String for SqliteError { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "SqliteError( code: {}, message: {} )", self.code, self.message) + } +} + impl SqliteError { fn from_handle(db: *mut ffi::Struct_sqlite3, code: c_int) -> SqliteError { let message = if db.is_null() { From b57322e2ca50566736175ae53eab3b51297842c7 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 20:58:42 -0600 Subject: [PATCH 4/7] Allow use of unstable APIs --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index e9d6037..2f9da4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ //! an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres). //! //! ```rust +//! #![allow(unstable)] //! extern crate rusqlite; //! extern crate time; //! @@ -48,6 +49,7 @@ //! } //! ``` #![feature(unsafe_destructor)] +#![allow(unstable)] extern crate libc; From 8617cde6b63b076f573b70a54377529bfbf14e48 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 21:17:49 -0600 Subject: [PATCH 5/7] Add `query_row_safe`. This is a `SqliteResult`-returning variant of `query_row`, which panics if the query fails or does not return at least one row. --- src/lib.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 2f9da4d..bc802f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -259,6 +259,35 @@ impl SqliteConnection { f(rows.next().expect("Query did not return a row").unwrap()) } + /// Convenience method to execute a query that is expected to return a single row. + /// + /// ## Example + /// + /// ```rust,no_run + /// # use rusqlite::{SqliteResult,SqliteConnection}; + /// fn preferred_locale(conn: &SqliteConnection) -> SqliteResult { + /// conn.query_row_safe("SELECT value FROM preferences WHERE name='locale'", &[], |row| { + /// row.get(0) + /// }) + /// } + /// ``` + /// + /// If the query returns more than one row, all rows except the first are ignored. + pub fn query_row_safe(&self, sql: &str, params: &[&ToSql], f: F) -> SqliteResult + where F: FnOnce(SqliteRow) -> T { + let mut stmt = try!(self.prepare(sql)); + let mut rows = try!(stmt.query(params)); + + if let Some(row) = rows.next() { + row.map(f) + } else { + Err(SqliteError{ + code: ffi::SQLITE_NOTICE, + message: "Query did not return a row".to_string(), + }) + } + } + /// Prepare a SQL statement for execution. /// /// ## Example @@ -768,6 +797,33 @@ mod test { } } + #[test] + fn test_query_row_safe() { + let db = checked_memory_handle(); + let sql = "BEGIN; + CREATE TABLE foo(x INTEGER); + INSERT INTO foo VALUES(1); + INSERT INTO foo VALUES(2); + INSERT INTO foo VALUES(3); + INSERT INTO foo VALUES(4); + END;"; + db.execute_batch(sql).unwrap(); + + assert_eq!(10i64, db.query_row_safe("SELECT SUM(x) FROM foo", &[], |r| { + r.get::(0) + }).unwrap()); + + let result = db.query_row_safe("SELECT x FROM foo WHERE x > 5", &[], |r| r.get::(0)); + let error = result.unwrap_err(); + + assert!(error.code == ffi::SQLITE_NOTICE); + assert!(error.message.as_slice() == "Query did not return a row"); + + let bad_query_result = db.query_row_safe("NOT A PROPER QUERY; test123", &[], |_| ()); + + assert!(bad_query_result.is_err()); + } + #[test] fn test_prepare_failures() { let db = checked_memory_handle(); From f84d96aab3c3fa65b8500ee5f8c8e580553eeca6 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 21:21:08 -0600 Subject: [PATCH 6/7] Bump version to 0.0.6 --- Cargo.toml | 2 +- Changelog.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1aca7a3..1e20b79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rusqlite" -version = "0.0.5" +version = "0.0.6" authors = ["John Gallagher "] description = "Ergonomic wrapper for SQLite" homepage = "https://github.com/jgallagher/rusqlite" diff --git a/Changelog.md b/Changelog.md index 8bd5da6..a907810 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,8 @@ +# Version 0.0.6 (2014-01-10) + +* Updates to track latest rustc changes (1.0.0-alpha). +* Add `query_row_safe`, a `SqliteResult`-returning variant of `query_row`. + # Version 0.0.5 (2014-01-07) * Updates to track latest rustc changes (closure syntax). From 288070e649a34b60751f784811d9eb06c39c4d61 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sat, 10 Jan 2015 21:22:42 -0600 Subject: [PATCH 7/7] Add CONTRIBUTORS.md --- CONTRIBUTORS.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CONTRIBUTORS.md diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..cca970f --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +rusqlite contributors (sorted alphabetically) +============================================= + +* [John Gallagher](https://github.com/jgallagher) +* [Marcus Klaas de Vries](https://github.com/marcusklaas)