Merge pull request #1 from thijsc/master

sync from upstream
pull/38/head
Zhang Cheng 7 years ago committed by GitHub
commit f8c1665e01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,13 @@
# 0.12.0
* Upgrade libmongoc to 1.8.2
* Update bson dependency to 0.11
* Parse MongoDB server responses with lossy UTF-8 decoding to work
around https://jira.mongodb.org/browse/SERVER-24007
# 0.11.0
* Update bson dependency to 0.10
* Use installed libmongoc if it right version is present on the system (thanks to Matrix-Zhang)
# 0.10.0 # 0.10.0
* Initial upgrade to mongo c driver 1.8.0, no support for new features yet * Initial upgrade to mongo c driver 1.8.0, no support for new features yet

@ -1,6 +1,6 @@
[package] [package]
name = "mongo_driver" name = "mongo_driver"
version = "0.10.0" version = "0.12.0"
authors = ["Thijs Cadier <thijs@appsignal.com>"] authors = ["Thijs Cadier <thijs@appsignal.com>"]
description = "Mongo Rust driver built on top of the Mongo C driver" description = "Mongo Rust driver built on top of the Mongo C driver"
readme = "README.md" readme = "README.md"
@ -21,11 +21,11 @@ name = "tests"
[dependencies] [dependencies]
libc = "^0.2" libc = "^0.2"
log = "^0.3" log = "^0.3"
bson = "^0.10" bson = "^0.11"
[dependencies.mongoc-sys] [dependencies.mongoc-sys]
path = "mongoc-sys" path = "mongoc-sys"
version = "1.8.0" version = "1.8.2-0"
[dev-dependencies] [dev-dependencies]
chrono = "^0.4" chrono = "^0.4"

@ -1,6 +1,6 @@
[package] [package]
name = "mongoc-sys" name = "mongoc-sys"
version = "1.8.0" version = "1.8.2-0"
description = "Sys package with installer and bindings for mongoc" description = "Sys package with installer and bindings for mongoc"
authors = ["Thijs Cadier <thijs@appsignal.com>"] authors = ["Thijs Cadier <thijs@appsignal.com>"]
build = "build.rs" build = "build.rs"

@ -4,26 +4,30 @@ use std::env;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
static VERSION: &'static str = "1.8.0"; // Should be the same major version as in the manifest
fn main() { fn main() {
let mongoc_version = env!("CARGO_PKG_VERSION")
.split('-')
.next()
.expect("Crate version is not valid");
if pkg_config::Config::new() if pkg_config::Config::new()
.atleast_version(VERSION) .atleast_version(mongoc_version)
.statik(true) .statik(true)
.probe("libmongoc-1.0") .probe("libmongoc-1.0")
.is_err() .is_err()
{ {
let out_dir_var = env::var("OUT_DIR").expect("No out dir"); let out_dir_var = env::var("OUT_DIR").expect("No out dir");
let out_dir = format!("{}/{}", out_dir_var, VERSION); let out_dir = format!("{}/{}", out_dir_var, mongoc_version);
let driver_src_path = format!("mongo-c-driver-{}", VERSION); let driver_src_path = format!("mongo-c-driver-{}", mongoc_version);
let libmongoc_path = Path::new(&out_dir).join("lib/libmongoc-1.0.a"); let libmongoc_path = Path::new(&out_dir).join("lib/libmongoc-1.0.a");
if !libmongoc_path.exists() { if !libmongoc_path.exists() {
// Download and extract driver archive // Download and extract driver archive
let url = format!( let url = format!(
"https://github.com/mongodb/mongo-c-driver/releases/download/{}/mongo-c-driver-{}.tar.gz", "https://github.com/mongodb/mongo-c-driver/releases/download/{}/mongo-c-driver-{}.tar.gz",
VERSION, mongoc_version,
VERSION mongoc_version
); );
assert!( assert!(
Command::new("curl").arg("-O") // Save to disk Command::new("curl").arg("-O") // Save to disk
@ -34,7 +38,7 @@ fn main() {
.success() .success()
); );
let archive_name = format!("mongo-c-driver-{}.tar.gz", VERSION); let archive_name = format!("mongo-c-driver-{}.tar.gz", mongoc_version);
assert!( assert!(
Command::new("tar") Command::new("tar")
.arg("xzf") .arg("xzf")

@ -42,6 +42,7 @@ impl Bsonc {
Ok(Bsonc{ inner: inner }) Ok(Bsonc{ inner: inner })
} }
/// Decode a bson from the C side to a document
pub fn as_document(&self) -> Result<bson::Document> { pub fn as_document(&self) -> Result<bson::Document> {
assert!(!self.inner.is_null()); assert!(!self.inner.is_null());
@ -63,6 +64,28 @@ impl Bsonc {
Ok(document) Ok(document)
} }
/// Decode a bson from the C side to a document with lossy UTF-8 decoding
pub fn as_document_utf8_lossy(&self) -> Result<bson::Document> {
assert!(!self.inner.is_null());
// This pointer should not be modified or freed
// See: http://mongoc.org/libbson/current/bson_get_data.html
let data_ptr = unsafe { bindings::bson_get_data(self.inner) };
assert!(!data_ptr.is_null());
let data_len = unsafe {
let bson = *self.inner;
bson.len
} as usize;
let mut slice = unsafe {
slice::from_raw_parts(data_ptr, data_len)
};
let document = try!(bson::decode_document_utf8_lossy(&mut slice));
Ok(document)
}
pub fn as_json(&self) -> String { pub fn as_json(&self) -> String {
assert!(!self.inner.is_null()); assert!(!self.inner.is_null());
let json_ptr = unsafe { bindings::bson_as_json(self.inner, ptr::null_mut()) }; let json_ptr = unsafe { bindings::bson_as_json(self.inner, ptr::null_mut()) };
@ -106,7 +129,18 @@ mod tests {
let bsonc = super::Bsonc::from_document(&document).unwrap(); let bsonc = super::Bsonc::from_document(&document).unwrap();
let decoded = bsonc.as_document().unwrap(); let decoded = bsonc.as_document().unwrap();
assert!(decoded.contains_key("key")); assert_eq!(decoded.get_str("key").unwrap(), "value");
}
#[test]
fn test_bsonc_from_and_as_document_invalid_utf8() {
let bytes = b"\x80\xae".to_vec();
let value = unsafe { String::from_utf8_unchecked(bytes) };
let document = doc! { "key" => value };
let bsonc = super::Bsonc::from_document(&document).unwrap();
let decoded = bsonc.as_document_utf8_lossy().unwrap();
assert_eq!(decoded.get_str("key").unwrap(), "<22><>");
} }
#[test] #[test]

@ -305,7 +305,7 @@ impl<'a> Client<'a> {
}; };
if success == 1 { if success == 1 {
match reply.as_document() { match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document), Ok(document) => return Ok(document),
Err(error) => return Err(error.into()) Err(error) => return Err(error.into())
} }

@ -342,7 +342,7 @@ impl<'a> Collection<'a> {
}; };
if success == 1 { if success == 1 {
match reply.as_document() { match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document), Ok(document) => return Ok(document),
Err(error) => return Err(error.into()) Err(error) => return Err(error.into())
} }
@ -547,7 +547,7 @@ impl<'a> Collection<'a> {
}; };
if success == 1 { if success == 1 {
match reply.as_document() { match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document), Ok(document) => return Ok(document),
Err(error) => return Err(error.into()) Err(error) => return Err(error.into())
} }
@ -884,7 +884,7 @@ impl<'a>BulkOperation<'a> {
) )
}; };
let document = match reply.as_document() { let document = match reply.as_document_utf8_lossy() {
Ok(document) => document, Ok(document) => document,
Err(error) => return Err(BulkOperationError{error: error.into(), reply: doc!{}}) Err(error) => return Err(BulkOperationError{error: error.into(), reply: doc!{}})
}; };

@ -116,7 +116,7 @@ impl<'a> Database<'a> {
}; };
if success == 1 { if success == 1 {
match reply.as_document() { match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document), Ok(document) => return Ok(document),
Err(error) => return Err(error.into()) Err(error) => return Err(error.into())
} }

@ -9,7 +9,9 @@ fn test_execute_error() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap(); let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None); let pool = ClientPool::new(uri, None);
let client = pool.pop(); let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_error"); let mut collection = client.get_collection("rust_driver_test", "bulk_operation_error");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None); let bulk_operation = collection.create_bulk_operation(None);
let result = bulk_operation.execute(); let result = bulk_operation.execute();
@ -24,11 +26,13 @@ fn test_basics() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap(); let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None); let pool = ClientPool::new(uri, None);
let client = pool.pop(); let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_basics"); let mut collection = client.get_collection("rust_driver_test", "bulk_operation_basics");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None); let bulk_operation = collection.create_bulk_operation(None);
let document = doc! {"key_1" => "Value 1"}; let document = doc! {"key_1" => "Value 1"};
bulk_operation.insert(&document).unwrap(); bulk_operation.insert(&document).expect("Could not insert");
assert!(bulk_operation.execute().is_ok()); assert!(bulk_operation.execute().is_ok());
let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap(); let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap();
@ -43,11 +47,13 @@ fn test_utf8() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap(); let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None); let pool = ClientPool::new(uri, None);
let client = pool.pop(); let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_utf8"); let mut collection = client.get_collection("rust_driver_test", "bulk_operation_utf8");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None); let bulk_operation = collection.create_bulk_operation(None);
let document = doc! {"key_1" => "kācaṃ śaknomyattum; nopahinasti mām."}; let document = doc! {"key_1" => "kācaṃ śaknomyattum; nopahinasti mām."};
bulk_operation.insert(&document).unwrap(); bulk_operation.insert(&document).expect("Could not insert");
assert!(bulk_operation.execute().is_ok()); assert!(bulk_operation.execute().is_ok());
let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap(); let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap();

Loading…
Cancel
Save