//! This driver is a thin wrapper around the production-ready [Mongo C driver](https://github.com/mongodb/mongo-c-driver). //! //! It aims to provide a safe and ergonomic Rust interface which handles all the gnarly usage details of //! the C driver for you. We use Rust's type system to make sure that we can only use the //! underlying C driver in the recommended way specified in it's [documentation](http://mongoc.org/libmongoc/current/). //! //! To get started create a client pool wrapped in an `Arc` so we can share it between threads. Then pop a client from it //! you can use to perform operations. //! //! # Example //! //! ``` //! use std::sync::Arc; //! use mongo_driver::client::{ClientPool,Uri}; //! //! let uri = Uri::new("mongodb://localhost:27017/").unwrap(); //! let pool = Arc::new(ClientPool::new(uri.clone(), None)); //! let client = pool.pop(); //! client.get_server_status(None).unwrap(); //! ``` //! //! See the documentation for the available modules to find out how you can use the driver beyond //! this. extern crate libc; extern crate mongoc_sys as mongoc; #[macro_use] extern crate bson; #[macro_use] extern crate log; #[macro_use] extern crate serde_derive; extern crate serde; use std::ffi::CStr; use std::ptr; use std::result; use std::sync::{Once,ONCE_INIT}; use mongoc::bindings; pub mod client; pub mod collection; pub mod cursor; pub mod database; pub mod flags; pub mod read_prefs; pub mod write_concern; mod bsonc; mod error; pub use error::{MongoError,BsoncError,MongoErrorDomain,MongoErrorCode,InvalidParamsError,BulkOperationError}; /// Result that's used in all functions that perform operations on the database. pub type Result = result::Result; /// Result that's used in bulk operations. pub type BulkOperationResult = result::Result; static MONGOC_INIT: Once = ONCE_INIT; /// Init mongo driver, needs to be called once before doing /// anything else. fn init() { MONGOC_INIT.call_once(|| { unsafe { // Init mongoc subsystem bindings::mongoc_init(); // Set mongoc log handler bindings::mongoc_log_set_handler( Some(mongoc_log_handler), ptr::null_mut() ); } }); } unsafe extern "C" fn mongoc_log_handler( log_level: bindings::mongoc_log_level_t, log_domain: *const ::libc::c_char, message: *const ::libc::c_char, _: *mut ::libc::c_void ) { let log_domain_str = CStr::from_ptr(log_domain).to_string_lossy(); let message_str = CStr::from_ptr(message).to_string_lossy(); let log_line = format!("mongoc: {} - {}", log_domain_str, message_str); match log_level { bindings::MONGOC_LOG_LEVEL_ERROR => error!("{}", log_line), bindings::MONGOC_LOG_LEVEL_CRITICAL => error!("{}", log_line), bindings::MONGOC_LOG_LEVEL_WARNING => warn!("{}", log_line), bindings::MONGOC_LOG_LEVEL_MESSAGE => info!("{}", log_line), bindings::MONGOC_LOG_LEVEL_INFO => info!("{}", log_line), bindings::MONGOC_LOG_LEVEL_DEBUG => debug!("{}", log_line), bindings::MONGOC_LOG_LEVEL_TRACE => trace!("{}", log_line), _ => panic!("Unknown mongoc log level") } } /// Options to configure both command and find operations. pub struct CommandAndFindOptions { /// Flags to use pub query_flags: flags::Flags, /// Number of documents to skip, zero to ignore pub skip: u32, /// Max number of documents to return, zero to ignore pub limit: u32, /// Number of documents in each batch, zero to ignore (default is 100) pub batch_size: u32, /// Fields to return, not all commands support this option pub fields: Option, /// Read prefs to use pub read_prefs: Option } impl CommandAndFindOptions { /// Default options used if none are provided. pub fn default() -> CommandAndFindOptions { CommandAndFindOptions { query_flags: flags::Flags::new(), skip: 0, limit: 0, batch_size: 0, fields: None, read_prefs: None } } pub fn with_fields(fields: bson::Document) -> CommandAndFindOptions { CommandAndFindOptions { query_flags: flags::Flags::new(), skip: 0, limit: 0, batch_size: 0, fields: Some(fields), 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)] mod tests { #[test] fn test_init() { super::init(); super::init(); } }