|  |  | @ -3,6 +3,7 @@ use std::ffi::CStr; | 
			
		
	
		
		
			
				
					
					|  |  |  | use std::borrow::Cow; |  |  |  | use std::borrow::Cow; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use mongoc::bindings; |  |  |  | use mongoc::bindings; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use bsonc; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use bson::Document; |  |  |  | use bson::Document; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -43,6 +44,35 @@ impl BulkOperationOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub struct FindAndModifyOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub sort:   Option<Document>, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub new:    bool, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub fields: Option<Document> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | impl FindAndModifyOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub fn default() -> FindAndModifyOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         FindAndModifyOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             sort:   None, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             new:    false, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             fields: None | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     fn fields_bsonc(&self) -> Option<bsonc::Bsonc> { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         match self.fields { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             Some(ref f) => Some(bsonc::Bsonc::from_document(f).unwrap()), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             None => None | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub enum FindAndModifyOperation<'a> { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Update(&'a Document), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Upsert(&'a Document), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Remove | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct CountOptions { |  |  |  | pub struct CountOptions { | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub query_flags: Flags<QueryFlag>, |  |  |  |     pub query_flags: Flags<QueryFlag>, | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub skip:        u32, |  |  |  |     pub skip:        u32, | 
			
		
	
	
		
		
			
				
					|  |  | @ -316,6 +346,76 @@ impl<'a> Collection<'a> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         )) |  |  |  |         )) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Update and return an object.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // This is a thin wrapper around the findAndModify command. Pass in
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // an operation that either updates, upserts or removes.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub fn find_and_modify( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         &'a self, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         query:     &Document, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         operation: FindAndModifyOperation<'a>, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         options:   Option<&FindAndModifyOptions> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ) -> Result<Document> { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         assert!(!self.inner.is_null()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let default_options = FindAndModifyOptions::default(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let options         = options.unwrap_or(&default_options); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let fields_bsonc    = options.fields_bsonc(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // Bsonc to store the reply
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let mut reply = Bsonc::new(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // Empty error that might be filled
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let mut error = BsoncError::empty(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // Do these before the mongoc call to make sure we keep
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // them around long enough.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let sort = match options.sort { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             Some(ref doc) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 try!(Bsonc::from_document(doc)).inner() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             None => ptr::null() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let update = match operation { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             FindAndModifyOperation::Update(ref doc) | FindAndModifyOperation::Upsert(ref doc) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 try!(Bsonc::from_document(doc)).inner() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             FindAndModifyOperation::Remove => ptr::null() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let success = unsafe { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             bindings::mongoc_collection_find_and_modify( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 self.inner, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 try!(Bsonc::from_document(&query)).inner(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 sort, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 update, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 match fields_bsonc { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     Some(ref f) => f.inner(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     None => ptr::null() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 match operation { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     FindAndModifyOperation::Remove => true, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     _ => false | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } as u8, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 match operation { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     FindAndModifyOperation::Upsert(_) => true, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     _ => false | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } as u8, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 options.new as u8, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 reply.mut_inner(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 error.mut_inner() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             ) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if success == 1 { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             match reply.as_document() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 Ok(document) => return Ok(document), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 Err(error)   => return Err(error.into()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             Err(error.into()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn get_name(&self) -> Cow<str> { |  |  |  |     pub fn get_name(&self) -> Cow<str> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let cstr = unsafe { |  |  |  |         let cstr = unsafe { | 
			
		
	
		
		
			
				
					
					|  |  |  |             CStr::from_ptr(bindings::mongoc_collection_get_name(self.inner)) |  |  |  |             CStr::from_ptr(bindings::mongoc_collection_get_name(self.inner)) | 
			
		
	
	
		
		
			
				
					|  |  | 
 |