Methods to take ownership of a database and collection

pull/4/head
Thijs Cadier 9 years ago
parent 6be7ce71f5
commit 7140cdd443

@ -13,7 +13,9 @@ use bson::Document;
use super::Result; use super::Result;
use super::BsoncError; use super::BsoncError;
use super::bsonc::Bsonc; use super::bsonc::Bsonc;
use super::collection::{Collection,CreatedBy}; use super::collection;
use super::collection::Collection;
use super::database;
use super::database::Database; use super::database::Database;
use super::uri::Uri; use super::uri::Uri;
use super::read_prefs::ReadPrefs; use super::read_prefs::ReadPrefs;
@ -233,30 +235,52 @@ pub struct Client<'a> {
} }
impl<'a> Client<'a> { impl<'a> Client<'a> {
/// Borrow a collection
pub fn get_collection<DBT: Into<Vec<u8>>, CT: Into<Vec<u8>>>(&'a self, db: DBT, collection: CT) -> Collection<'a> { pub fn get_collection<DBT: Into<Vec<u8>>, CT: Into<Vec<u8>>>(&'a self, db: DBT, collection: CT) -> Collection<'a> {
assert!(!self.inner.is_null()); assert!(!self.inner.is_null());
let coll = unsafe { let coll = unsafe { self.collection_ptr(db.into(), collection.into()) };
let db_cstring = CString::new(db).unwrap(); Collection::new(collection::CreatedBy::BorrowedClient(self), coll)
let collection_cstring = CString::new(collection).unwrap(); }
bindings::mongoc_client_get_collection(
self.inner, /// Take a collection, client is owned by the collection so the collection can easily
db_cstring.as_ptr(), /// be passed around
collection_cstring.as_ptr() pub fn take_collection<DBT: Into<Vec<u8>>, CT: Into<Vec<u8>>>(self, db: DBT, collection: CT) -> Collection<'a> {
) assert!(!self.inner.is_null());
}; let coll = unsafe { self.collection_ptr(db.into(), collection.into()) };
Collection::new(CreatedBy::Client(self), coll) Collection::new(collection::CreatedBy::OwnedClient(self), coll)
}
unsafe fn collection_ptr(&self, db: Vec<u8>, collection: Vec<u8>) -> *mut bindings::mongoc_collection_t {
let db_cstring = CString::new(db).unwrap();
let collection_cstring = CString::new(collection).unwrap();
bindings::mongoc_client_get_collection(
self.inner,
db_cstring.as_ptr(),
collection_cstring.as_ptr()
)
} }
/// Borrow a database
pub fn get_database<S: Into<Vec<u8>>>(&'a self, db: S) -> Database<'a> { pub fn get_database<S: Into<Vec<u8>>>(&'a self, db: S) -> Database<'a> {
assert!(!self.inner.is_null()); assert!(!self.inner.is_null());
let coll = unsafe { let coll = unsafe { self.database_ptr(db.into()) };
let db_cstring = CString::new(db).unwrap(); Database::new(database::CreatedBy::BorrowedClient(self), coll)
bindings::mongoc_client_get_database( }
self.inner,
db_cstring.as_ptr() /// Take a database, client is owned by the database so the database can easily
) /// be passed around
}; pub fn take_database<S: Into<Vec<u8>>>(self, db: S) -> Database<'a> {
Database::new(self, coll) assert!(!self.inner.is_null());
let coll = unsafe { self.database_ptr(db.into()) };
Database::new(database::CreatedBy::OwnedClient(self), coll)
}
unsafe fn database_ptr(&self, db: Vec<u8>) -> *mut bindings::mongoc_database_t {
let db_cstring = CString::new(db).unwrap();
bindings::mongoc_client_get_database(
self.inner,
db_cstring.as_ptr()
)
} }
/// Queries the server for the current server status. /// Queries the server for the current server status.

@ -21,8 +21,10 @@ use super::write_concern::WriteConcern;
use super::read_prefs::ReadPrefs; use super::read_prefs::ReadPrefs;
pub enum CreatedBy<'a> { pub enum CreatedBy<'a> {
Client(&'a Client<'a>), BorrowedClient(&'a Client<'a>),
Database(&'a Database<'a>) OwnedClient(Client<'a>),
BorrowedDatabase(&'a Database<'a>),
OwnedDatabase(Database<'a>)
} }
pub struct Collection<'a> { pub struct Collection<'a> {

@ -16,20 +16,25 @@ use super::cursor;
use super::cursor::Cursor; use super::cursor::Cursor;
use flags::FlagsValue; use flags::FlagsValue;
pub enum CreatedBy<'a> {
BorrowedClient(&'a Client<'a>),
OwnedClient(Client<'a>)
}
pub struct Database<'a> { pub struct Database<'a> {
_client: &'a Client<'a>, _created_by: CreatedBy<'a>,
inner: *mut bindings::mongoc_database_t inner: *mut bindings::mongoc_database_t
} }
impl<'a> Database<'a> { impl<'a> Database<'a> {
pub fn new( pub fn new(
client: &'a Client<'a>, created_by: CreatedBy<'a>,
inner: *mut bindings::mongoc_database_t inner: *mut bindings::mongoc_database_t
) -> Database<'a> { ) -> Database<'a> {
assert!(!inner.is_null()); assert!(!inner.is_null());
Database { Database {
_client: client, _created_by: created_by,
inner: inner inner: inner
} }
} }
@ -145,22 +150,33 @@ impl<'a> Database<'a> {
}; };
if error.is_empty() { if error.is_empty() {
Ok(Collection::new(collection::CreatedBy::Database(self), coll)) Ok(Collection::new(collection::CreatedBy::BorrowedDatabase(self), coll))
} else { } else {
Err(error.into()) Err(error.into())
} }
} }
/// Borrow a collection
pub fn get_collection<S: Into<Vec<u8>>>(&self, collection: S) -> Collection { pub fn get_collection<S: Into<Vec<u8>>>(&self, collection: S) -> Collection {
assert!(!self.inner.is_null()); assert!(!self.inner.is_null());
let coll = unsafe { let coll = unsafe { self.collection_ptr(collection.into()) };
let collection_cstring = CString::new(collection).unwrap(); Collection::new(collection::CreatedBy::BorrowedDatabase(self), coll)
bindings::mongoc_database_get_collection( }
self.inner,
collection_cstring.as_ptr() /// Take a collection, database is owned by the collection so the collection can easily
) /// be passed around
}; pub fn take_collection<S: Into<Vec<u8>>>(self, collection: S) -> Collection<'a> {
Collection::new(collection::CreatedBy::Database(self), coll) assert!(!self.inner.is_null());
let coll = unsafe { self.collection_ptr(collection.into()) };
Collection::new(collection::CreatedBy::OwnedDatabase(self), coll)
}
unsafe fn collection_ptr(&self, collection: Vec<u8>) -> *mut bindings::mongoc_collection_t {
let collection_cstring = CString::new(collection).unwrap();
bindings::mongoc_database_get_collection(
self.inner,
collection_cstring.as_ptr()
)
} }
pub fn get_name(&self) -> Cow<str> { pub fn get_name(&self) -> Cow<str> {

@ -6,7 +6,7 @@ use mongo_driver::uri::Uri;
use mongo_driver::client::{ClientPool,SslOptions}; use mongo_driver::client::{ClientPool,SslOptions};
#[test] #[test]
fn test_new_pool_and_pop_client() { fn test_new_pool_pop_client_and_borrow_collection() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap(); let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri.clone(), None); let pool = ClientPool::new(uri.clone(), None);
assert_eq!(pool.get_uri(), &uri); assert_eq!(pool.get_uri(), &uri);
@ -22,6 +22,32 @@ fn test_new_pool_and_pop_client() {
assert_eq!("items", collection.get_name().to_mut()); assert_eq!("items", collection.get_name().to_mut());
} }
#[test]
fn test_new_pool_pop_client_and_take_collection() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri.clone(), None);
assert_eq!(pool.get_uri(), &uri);
// Pop a client and take collection
let client = pool.pop();
let collection = client.take_collection("rust_test", "items");
assert_eq!("items", collection.get_name().to_mut());
}
#[test]
fn test_new_pool_pop_client_and_take_database_and_collection() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri.clone(), None);
assert_eq!(pool.get_uri(), &uri);
// Pop a client and take database and collection
let client = pool.pop();
let database = client.take_database("rust_test");
assert_eq!("rust_test", database.get_name().to_mut());
let collection = database.take_collection("items");
assert_eq!("items", collection.get_name().to_mut());
}
#[test] #[test]
fn test_new_pool_and_pop_client_in_threads() { fn test_new_pool_and_pop_client_in_threads() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap(); let uri = Uri::new("mongodb://localhost:27017/").unwrap();

Loading…
Cancel
Save