mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 19:41:37 +08:00
Merge pull request #8 from jgallagher/unboxed-closures
Updates for latest rust changes
This commit is contained in:
commit
60c9a04161
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rusqlite"
|
name = "rusqlite"
|
||||||
version = "0.0.4"
|
version = "0.0.5"
|
||||||
authors = ["John Gallagher <jgallagher@bignerdranch.com>"]
|
authors = ["John Gallagher <jgallagher@bignerdranch.com>"]
|
||||||
description = "Ergonomic wrapper for SQLite"
|
description = "Ergonomic wrapper for SQLite"
|
||||||
homepage = "https://github.com/jgallagher/rusqlite"
|
homepage = "https://github.com/jgallagher/rusqlite"
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
# Version 0.0.5 (2014-01-07)
|
||||||
|
|
||||||
|
* Updates to track latest rustc changes (closure syntax).
|
||||||
|
* Updates to track latest rust stdlib changes (`std::c_str` -> `std::ffi`).
|
||||||
|
|
||||||
# Version 0.0.4 (2014-01-05)
|
# Version 0.0.4 (2014-01-05)
|
||||||
|
|
||||||
* Updates to track latest rustc changes.
|
* Updates to track latest rustc changes.
|
||||||
|
@ -13,7 +13,7 @@ extern crate time;
|
|||||||
use time::Timespec;
|
use time::Timespec;
|
||||||
use rusqlite::SqliteConnection;
|
use rusqlite::SqliteConnection;
|
||||||
|
|
||||||
#[deriving(Show)]
|
#[derive(Show)]
|
||||||
struct Person {
|
struct Person {
|
||||||
id: i32,
|
id: i32,
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![allow(raw_pointer_deriving)]
|
#![allow(raw_pointer_derive)]
|
||||||
/* Running `target/bindgen /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sqlite3.h -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/6.0/include` */
|
/* Running `target/bindgen /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sqlite3.h -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/6.0/include` */
|
||||||
/* automatically generated by rust-bindgen */
|
/* automatically generated by rust-bindgen */
|
||||||
|
|
||||||
|
37
src/lib.rs
37
src/lib.rs
@ -47,10 +47,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
#![feature(globs)]
|
|
||||||
#![feature(unsafe_destructor)]
|
#![feature(unsafe_destructor)]
|
||||||
#![feature(macro_rules)]
|
|
||||||
#![feature(associated_types)]
|
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
@ -59,7 +56,9 @@ use std::ptr;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::{Rc};
|
use std::rc::{Rc};
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::c_str::{CString, ToCStr};
|
use std::ffi::{CString};
|
||||||
|
use std::ffi as std_ffi;
|
||||||
|
use std::str;
|
||||||
use libc::{c_int, c_void, c_char};
|
use libc::{c_int, c_void, c_char};
|
||||||
|
|
||||||
use types::{ToSql, FromSql};
|
use types::{ToSql, FromSql};
|
||||||
@ -80,8 +79,9 @@ mod transaction;
|
|||||||
pub type SqliteResult<T> = Result<T, SqliteError>;
|
pub type SqliteResult<T> = Result<T, SqliteError>;
|
||||||
|
|
||||||
unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
|
unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
|
||||||
let c_str = CString::new(errmsg, false);
|
let c_slice = std_ffi::c_str_to_bytes(&errmsg);
|
||||||
c_str.as_str().unwrap_or("Invalid error message encoding").to_string()
|
let utf8_str = str::from_utf8(c_slice);
|
||||||
|
utf8_str.unwrap_or("Invalid string encoding").to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encompasses an error result from a call to the SQLite C API.
|
/// Encompasses an error result from a call to the SQLite C API.
|
||||||
@ -244,7 +244,8 @@ impl SqliteConnection {
|
|||||||
/// * The query does not successfully return at least one row.
|
/// * The query does not successfully return at least one row.
|
||||||
///
|
///
|
||||||
/// If the query returns more than one row, all rows except the first are ignored.
|
/// If the query returns more than one row, all rows except the first are ignored.
|
||||||
pub fn query_row<T>(&self, sql: &str, params: &[&ToSql], f: |SqliteRow| -> T) -> T {
|
pub fn query_row<T, F>(&self, sql: &str, params: &[&ToSql], f: F) -> T
|
||||||
|
where F: FnOnce(SqliteRow) -> T {
|
||||||
let mut stmt = self.prepare(sql).unwrap();
|
let mut stmt = self.prepare(sql).unwrap();
|
||||||
let mut rows = stmt.query(params).unwrap();
|
let mut rows = stmt.query(params).unwrap();
|
||||||
f(rows.next().expect("Query did not return a row").unwrap())
|
f(rows.next().expect("Query did not return a row").unwrap())
|
||||||
@ -313,9 +314,10 @@ bitflags! {
|
|||||||
|
|
||||||
impl InnerSqliteConnection {
|
impl InnerSqliteConnection {
|
||||||
fn open_with_flags(path: &str, flags: SqliteOpenFlags) -> SqliteResult<InnerSqliteConnection> {
|
fn open_with_flags(path: &str, flags: SqliteOpenFlags) -> SqliteResult<InnerSqliteConnection> {
|
||||||
path.with_c_str(|c_path| unsafe {
|
let c_path = CString::from_slice(path.as_bytes());
|
||||||
|
unsafe {
|
||||||
let mut db: *mut ffi::sqlite3 = mem::uninitialized();
|
let mut db: *mut ffi::sqlite3 = mem::uninitialized();
|
||||||
let r = ffi::sqlite3_open_v2(c_path, &mut db, flags.bits(), ptr::null());
|
let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), ptr::null());
|
||||||
if r != ffi::SQLITE_OK {
|
if r != ffi::SQLITE_OK {
|
||||||
let e = if db.is_null() {
|
let e = if db.is_null() {
|
||||||
SqliteError{ code: r,
|
SqliteError{ code: r,
|
||||||
@ -335,7 +337,7 @@ impl InnerSqliteConnection {
|
|||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
Ok(InnerSqliteConnection{ db: db })
|
Ok(InnerSqliteConnection{ db: db })
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_result(&mut self, code: c_int) -> SqliteResult<()> {
|
fn decode_result(&mut self, code: c_int) -> SqliteResult<()> {
|
||||||
@ -353,9 +355,10 @@ impl InnerSqliteConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn execute_batch(&mut self, sql: &str) -> SqliteResult<()> {
|
fn execute_batch(&mut self, sql: &str) -> SqliteResult<()> {
|
||||||
sql.with_c_str(|c_sql| unsafe {
|
let c_sql = CString::from_slice(sql.as_bytes());
|
||||||
|
unsafe {
|
||||||
let mut errmsg: *mut c_char = mem::uninitialized();
|
let mut errmsg: *mut c_char = mem::uninitialized();
|
||||||
let r = ffi::sqlite3_exec(self.db, c_sql, None, ptr::null_mut(), &mut errmsg);
|
let r = ffi::sqlite3_exec(self.db, c_sql.as_ptr(), None, ptr::null_mut(), &mut errmsg);
|
||||||
if r == ffi::SQLITE_OK {
|
if r == ffi::SQLITE_OK {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -363,7 +366,7 @@ impl InnerSqliteConnection {
|
|||||||
ffi::sqlite3_free(errmsg as *mut c_void);
|
ffi::sqlite3_free(errmsg as *mut c_void);
|
||||||
Err(SqliteError{ code: r, message: message })
|
Err(SqliteError{ code: r, message: message })
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_insert_rowid(&self) -> i64 {
|
fn last_insert_rowid(&self) -> i64 {
|
||||||
@ -376,10 +379,12 @@ impl InnerSqliteConnection {
|
|||||||
conn: &'a SqliteConnection,
|
conn: &'a SqliteConnection,
|
||||||
sql: &str) -> SqliteResult<SqliteStatement<'a>> {
|
sql: &str) -> SqliteResult<SqliteStatement<'a>> {
|
||||||
let mut c_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() };
|
let mut c_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() };
|
||||||
let r = sql.with_c_str(|c_sql| unsafe {
|
let c_sql = CString::from_slice(sql.as_bytes());
|
||||||
|
let r = unsafe {
|
||||||
let len_with_nul = (sql.len() + 1) as c_int;
|
let len_with_nul = (sql.len() + 1) as c_int;
|
||||||
ffi::sqlite3_prepare_v2(self.db, c_sql, len_with_nul, &mut c_stmt, ptr::null_mut())
|
ffi::sqlite3_prepare_v2(self.db, c_sql.as_ptr(), len_with_nul, &mut c_stmt,
|
||||||
});
|
ptr::null_mut())
|
||||||
|
};
|
||||||
self.decode_result(r).map(|_| {
|
self.decode_result(r).map(|_| {
|
||||||
SqliteStatement::new(conn, c_stmt)
|
SqliteStatement::new(conn, c_stmt)
|
||||||
})
|
})
|
||||||
|
22
src/types.rs
22
src/types.rs
@ -54,9 +54,11 @@
|
|||||||
|
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
use libc::{c_int, c_double};
|
use libc::{c_int, c_double, c_char};
|
||||||
use std::c_str::{CString, ToCStr};
|
use std::ffi as std_ffi;
|
||||||
|
use std::ffi::{CString};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::str;
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use super::{SqliteResult, SqliteError};
|
use super::{SqliteResult, SqliteError};
|
||||||
|
|
||||||
@ -88,9 +90,8 @@ raw_to_impl!(c_double, sqlite3_bind_double);
|
|||||||
|
|
||||||
impl<'a> ToSql for &'a str {
|
impl<'a> ToSql for &'a str {
|
||||||
unsafe fn bind_parameter(&self, stmt: *mut ffi::sqlite3_stmt, col: c_int) -> c_int {
|
unsafe fn bind_parameter(&self, stmt: *mut ffi::sqlite3_stmt, col: c_int) -> c_int {
|
||||||
self.with_c_str(|c_str| {
|
let c_str = CString::from_slice(self.as_bytes());
|
||||||
ffi::sqlite3_bind_text(stmt, col, c_str, -1, Some(ffi::SQLITE_TRANSIENT()))
|
ffi::sqlite3_bind_text(stmt, col, c_str.as_ptr(), -1, Some(ffi::SQLITE_TRANSIENT()))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +171,12 @@ impl FromSql for String {
|
|||||||
if c_text.is_null() {
|
if c_text.is_null() {
|
||||||
Ok("".to_string())
|
Ok("".to_string())
|
||||||
} else {
|
} else {
|
||||||
match CString::new(mem::transmute(c_text), false).as_str() {
|
let c_text = c_text as *const c_char;
|
||||||
Some(s) => Ok(s.to_string()),
|
let c_slice = std_ffi::c_str_to_bytes(&c_text);
|
||||||
None => Err(SqliteError{ code: ffi::SQLITE_MISMATCH,
|
let utf8_str = str::from_utf8(c_slice);
|
||||||
message: "Could not convert text to UTF-8".to_string() })
|
utf8_str
|
||||||
}
|
.map(|s| { s.to_string() })
|
||||||
|
.map_err(|e| { SqliteError{code: 0, message: e.to_string()} })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user