diff --git a/src/collection.rs b/src/collection.rs index 20edae0..9a5953d 100644 --- a/src/collection.rs +++ b/src/collection.rs @@ -129,8 +129,9 @@ impl<'a> Collection<'a> { let default_options = CommandAndFindOptions::default(); let options = options.unwrap_or(&default_options); + let fields_bsonc = options.fields_bsonc(); - let inner = unsafe { + let cursor_ptr = unsafe { bindings::mongoc_collection_command( self.inner, options.query_flags.flags(), @@ -138,10 +139,8 @@ impl<'a> Collection<'a> { options.limit, options.batch_size, try!(Bsonc::from_document(&command)).inner(), - match options.fields { - Some(ref f) => { - try!(Bsonc::from_document(f)).inner() - }, + match fields_bsonc { + Some(ref f) => f.inner(), None => ptr::null() }, match options.read_prefs { @@ -151,11 +150,15 @@ impl<'a> Collection<'a> { ) }; - if inner.is_null() { + if cursor_ptr.is_null() { return Err(InvalidParamsError.into()) } - Ok(Cursor::new(cursor::CreatedBy::Collection(self), inner)) + Ok(Cursor::new( + cursor::CreatedBy::Collection(self), + cursor_ptr, + fields_bsonc + )) } pub fn count( @@ -240,8 +243,9 @@ impl<'a> Collection<'a> { let default_options = CommandAndFindOptions::default(); let options = options.unwrap_or(&default_options); + let fields_bsonc = options.fields_bsonc(); - let inner = unsafe { + let cursor_ptr = unsafe { bindings::mongoc_collection_find( self.inner, options.query_flags.flags(), @@ -249,10 +253,8 @@ impl<'a> Collection<'a> { options.limit, options.batch_size, try!(Bsonc::from_document(query)).inner(), - match options.fields { - Some(ref f) => { - try!(Bsonc::from_document(f)).inner() - }, + match fields_bsonc { + Some(ref f) => f.inner(), None => ptr::null() }, match options.read_prefs { @@ -262,11 +264,15 @@ impl<'a> Collection<'a> { ) }; - if inner.is_null() { + if cursor_ptr.is_null() { return Err(InvalidParamsError.into()) } - Ok(Cursor::new(cursor::CreatedBy::Collection(self), inner)) + Ok(Cursor::new( + cursor::CreatedBy::Collection(self), + cursor_ptr, + fields_bsonc + )) } pub fn get_name(&self) -> Cow { diff --git a/src/cursor.rs b/src/cursor.rs index 14047e1..87c7890 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -25,20 +25,25 @@ pub struct Cursor<'a> { _created_by: CreatedBy<'a>, inner: *mut bindings::mongoc_cursor_t, tailing: bool, - tail_wait_time_ms: u32 + tail_wait_time_ms: u32, + // Become owner of bsonc because the cursor needs it + // to be allocated for it's entire lifetime + _fields: Option } impl<'a> Cursor<'a> { pub fn new( created_by: CreatedBy<'a>, - inner: *mut bindings::mongoc_cursor_t + inner: *mut bindings::mongoc_cursor_t, + fields: Option ) -> Cursor<'a> { assert!(!inner.is_null()); Cursor { _created_by: created_by, inner: inner, tailing: false, - tail_wait_time_ms: 0 + tail_wait_time_ms: 0, + _fields: fields } } diff --git a/src/database.rs b/src/database.rs index 8e8cc41..1b1e1ec 100644 --- a/src/database.rs +++ b/src/database.rs @@ -45,8 +45,9 @@ impl<'a> Database<'a> { let default_options = CommandAndFindOptions::default(); let options = options.unwrap_or(&default_options); + let fields_bsonc = options.fields_bsonc(); - let inner = unsafe { + let cursor_ptr = unsafe { bindings::mongoc_database_command( self.inner, options.query_flags.flags(), @@ -54,10 +55,8 @@ impl<'a> Database<'a> { options.limit, options.batch_size, try!(Bsonc::from_document(&command)).inner(), - match options.fields { - Some(ref f) => { - try!(Bsonc::from_document(f)).inner() - }, + match fields_bsonc { + Some(ref f) => f.inner(), None => ptr::null() }, match options.read_prefs { @@ -67,11 +66,15 @@ impl<'a> Database<'a> { ) }; - if inner.is_null() { + if cursor_ptr.is_null() { return Err(InvalidParamsError.into()) } - Ok(Cursor::new(cursor::CreatedBy::Database(self), inner)) + Ok(Cursor::new( + cursor::CreatedBy::Database(self), + cursor_ptr, + fields_bsonc + )) } pub fn create_collection>>( diff --git a/src/lib.rs b/src/lib.rs index 898fa50..cc3f9f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,13 @@ impl CommandAndFindOptions { read_prefs: None } } + + fn fields_bsonc(&self) -> Option { + match self.fields { + Some(ref f) => Some(bsonc::Bsonc::from_document(f).unwrap()), + None => None + } + } } #[cfg(test)]