use std::ffi::{CStr, CString};
use std::ptr;
use std::mem;
use crate::sys::*;
use crate::core::bsonc::Bsonc;
use crate::core::read_preference::ReadPreference;
use crate::core::read_concern::ReadConcern;
use crate::core::write_concern::WriteConcern;
use crate::core::find_and_modify::FindAndModifyOpts;
use crate::core::error::MongocError;
use crate::core::cursor::Cursor;
use crate::core::change_stream::ChangeStream;
use crate::error::Result;
pub struct Collection(*mut mongoc_collection_t);
impl Collection {
pub fn from_ptr(ptr: *mut mongoc_collection_t) -> Collection {
assert!(!ptr.is_null());
Collection(ptr)
}
pub fn as_ptr(&self) -> *const mongoc_collection_t {
assert!(!self.0.is_null());
self.0
}
pub fn as_mut_ptr(&self) -> *mut mongoc_collection_t {
assert!(!self.0.is_null());
self.0
}
pub fn name(&self) -> String {
assert!(!self.0.is_null());
let s = unsafe {
let ptr = mongoc_collection_get_name(self.0);
CStr::from_ptr(ptr)
};
s.to_string_lossy().to_string()
}
pub fn command_simple(
&self,
command: &Bsonc,
read_prefs: Option<&ReadPreference>
) -> Result<Bsonc> {
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let mut error = MongocError::empty();
let reply = Bsonc::new();
if unsafe { mongoc_collection_command_simple(
self.0,
command.as_ptr(),
read_prefs_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn command(
&self,
command: &Bsonc,
read_prefs: Option<&ReadPreference>,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let mut error = MongocError::empty();
let reply = Bsonc::new();
if unsafe { mongoc_collection_command_with_opts(
self.0,
command.as_ptr(),
read_prefs_ptr,
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn count_documents(
&self,
filter: &Bsonc,
opts: Option<&Bsonc>,
read_prefs: Option<&ReadPreference>
) -> Result<(Bsonc, i64)> {
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let mut error = MongocError::empty();
let reply = Bsonc::new();
let count = unsafe {
mongoc_collection_count_documents(
self.0,
filter.as_ptr(),
opts_ptr,
read_prefs_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
)
};
if count < 0 {
return Err(error.into())
}
Ok((reply, count))
}
pub fn estimated_document_count(
&self,
opts: Option<&Bsonc>,
read_prefs: Option<&ReadPreference>
) -> Result<(Bsonc, i64)> {
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let mut error = MongocError::empty();
let reply = Bsonc::new();
let count = unsafe {
mongoc_collection_estimated_document_count(
self.0,
opts_ptr,
read_prefs_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
)
};
if count < 0 {
return Err(error.into())
}
Ok((reply, count))
}
pub fn find_with_opts(
&self,
filter: &Bsonc,
opts: Option<&Bsonc>,
read_prefs: Option<&ReadPreference>
) -> Cursor {
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let cursor = unsafe {
mongoc_collection_find_with_opts(
self.0,
filter.as_ptr(),
opts_ptr,
read_prefs_ptr
)
};
Cursor::from_ptr(cursor)
}
pub fn find_and_modify_with_opts(
&self,
query: &Bsonc,
opts: &FindAndModifyOpts
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
if unsafe { mongoc_collection_find_and_modify_with_opts(
self.0,
query.as_ptr(),
opts.as_ptr(),
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn insert_one(
&self,
doc: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_insert_one(
self.0,
doc.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn insert_many(
&self,
docs: &[Bsonc],
opts: Option<&Bsonc>,
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let mut docs: Vec<*const _> = docs.iter().map(|b| b.as_ptr()).collect();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_insert_many(
self.0,
docs.as_mut_ptr(),
docs.len(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn update_one(
&self,
selector: &Bsonc,
update: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_update_one(
self.0,
selector.as_ptr(),
update.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn update_many(
&self,
selector: &Bsonc,
update: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_update_many(
self.0,
selector.as_ptr(),
update.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn delete_one(
&self,
selector: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_delete_one(
self.0,
selector.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn delete_many(
&self,
selector: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_delete_many(
self.0,
selector.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn replace_one(
&self,
selector: &Bsonc,
replace: &Bsonc,
opts: Option<&Bsonc>
) -> Result<Bsonc> {
let mut error = MongocError::empty();
let reply = Bsonc::new();
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
if unsafe { mongoc_collection_replace_one(
self.0,
selector.as_ptr(),
replace.as_ptr(),
opts_ptr,
reply.as_mut_ptr(),
error.as_mut_ptr()
) } {
return Ok(reply)
}
Err(error.into())
}
pub fn aggregate(
&self,
flags: u32,
pipeline: &Bsonc,
opts: Option<&Bsonc>,
read_prefs: Option<&ReadPreference>
) -> Cursor {
let read_prefs_ptr = read_prefs.map(|r| r.as_ptr()).unwrap_or(ptr::null());
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let cursor = unsafe {
mongoc_collection_aggregate(
self.0,
flags,
pipeline.as_ptr(),
opts_ptr,
read_prefs_ptr
)
};
Cursor::from_ptr(cursor)
}
pub fn watch(
&self,
pipeline: &Bsonc,
opts: Option<&Bsonc>
) -> ChangeStream {
let opts_ptr = opts.map(|o| o.as_ptr()).unwrap_or(ptr::null());
let change_stream = unsafe {
mongoc_collection_watch(
self.0,
pipeline.as_ptr(),
opts_ptr
)
};
ChangeStream::from_ptr(change_stream)
}
pub fn drop(&self) -> Result<()> {
let mut error = MongocError::empty();
if unsafe { mongoc_collection_drop(
self.0,
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn drop_with_opts(
&self,
opts: &Bsonc
) -> Result<()> {
let mut error = MongocError::empty();
if unsafe { mongoc_collection_drop_with_opts(
self.0,
opts.as_ptr(),
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn drop_index(&self, index_name: &str) -> Result<()> {
let index_name = CString::new(index_name).expect("CString::new failed");
let mut error = MongocError::empty();
if unsafe { mongoc_collection_drop_index(
self.0,
index_name.as_ptr(),
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn drop_index_with_opts(&self, index_name: &str, opts: &Bsonc) -> Result<()> {
let index_name = CString::new(index_name).expect("CString::new failed");
let mut error = MongocError::empty();
if unsafe { mongoc_collection_drop_index_with_opts(
self.0,
index_name.as_ptr(),
opts.as_ptr(),
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn keys_to_index_string(&self, keys: &Bsonc) -> String {
let ptr = unsafe {
mongoc_collection_keys_to_index_string(keys.as_ptr())
};
assert!(!ptr.is_null());
let s = unsafe { CStr::from_ptr(ptr as *const _) };
let s = s.to_string_lossy().to_string();
unsafe { bson_free(ptr as _); }
s
}
pub fn rename(
&self,
new_db: &str,
new_name: &str,
drop_target_before_rename: bool
) -> Result<()> {
let new_db = CString::new(new_db).expect("CString::new failed");
let new_name = CString::new(new_name).expect("CString::new failed");
let mut error = MongocError::empty();
if unsafe { mongoc_collection_rename(
self.0,
new_db.as_ptr(),
new_name.as_ptr(),
drop_target_before_rename,
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn rename_with_opts(
&self,
new_db: &str,
new_name: &str,
drop_target_before_rename: bool,
opts: &Bsonc
) -> Result<()> {
let new_db = CString::new(new_db).expect("CString::new failed");
let new_name = CString::new(new_name).expect("CString::new failed");
let mut error = MongocError::empty();
if unsafe { mongoc_collection_rename_with_opts(
self.0,
new_db.as_ptr(),
new_name.as_ptr(),
drop_target_before_rename,
opts.as_ptr(),
error.as_mut_ptr()
) } {
return Ok(())
}
Err(error.into())
}
pub fn read_prefs(&self) -> ReadPreference {
assert!(!self.0.is_null());
let ptr = unsafe { mongoc_collection_get_read_prefs(self.0) };
let read_preference = ReadPreference::from_ptr(ptr as *mut _);
let read_preference2 = read_preference.clone();
mem::forget(read_preference);
read_preference2
}
pub fn set_read_prefs(&self, read_prefs: &ReadPreference) {
assert!(!self.0.is_null());
unsafe { mongoc_collection_set_read_prefs(self.0, read_prefs.as_ptr()) }
}
pub fn read_concern(&self) -> ReadConcern {
assert!(!self.0.is_null());
let ptr = unsafe { mongoc_collection_get_read_concern(self.0) };
let read_concern = ReadConcern::from_ptr(ptr as *mut _);
let read_concern2 = read_concern.clone();
mem::forget(read_concern);
read_concern2
}
pub fn set_read_concern(&self, read_concern: &ReadConcern) {
assert!(!self.0.is_null());
unsafe { mongoc_collection_set_read_concern(self.0, read_concern.as_ptr()) }
}
pub fn write_concern(&self) -> WriteConcern {
assert!(!self.0.is_null());
let ptr = unsafe { mongoc_collection_get_write_concern(self.0) };
let write_concern = WriteConcern::from_ptr(ptr as *mut _);
let write_concern2 = write_concern.clone();
mem::forget(write_concern);
write_concern2
}
pub fn set_write_concern(&self, write_concern: &WriteConcern) {
assert!(!self.0.is_null());
unsafe { mongoc_collection_set_write_concern(self.0, write_concern.as_ptr()) }
}
}
impl Drop for Collection {
fn drop(&mut self) {
assert!(!self.0.is_null());
unsafe { mongoc_collection_destroy(self.0) }
}
}
impl Clone for Collection {
fn clone(&self) -> Collection {
assert!(!self.0.is_null());
unsafe { Collection(mongoc_collection_copy(self.0)) }
}
}