use polodb_core::{Result, CollectionT};
use polodb_core::bson::{doc, DateTime, Document};
mod common;
use common::{
prepare_db,
create_file_and_return_db_with_items,
};
static TEST_SIZE: usize = 1000;
#[test]
fn test_multiple_find_one() {
vec![
(prepare_db("test-multiple-find-one").unwrap(), true),
].iter().for_each(|(db, _is_file)| {
let metrics = db.metrics();
metrics.enable();
{
let collection = db.collection("config");
collection.insert_many(vec![
doc! {
"_id": "c1",
"value": "c1",
},
doc! {
"_id": "c2",
"value": "c2",
},
doc! {
"_id": "c3",
"value": "c3",
},
]).unwrap();
assert_eq!(collection.count_documents().unwrap(), 3);
}
{
let collection = db.collection::<Document>("config");
collection.update_many(doc! {
"_id": "c2"
}, doc! {
"$set": doc! {
"value": "c33",
},
}).unwrap();
collection.update_many(doc! {
"_id": "c2",
}, doc! {
"$set": doc! {
"value": "c22",
},
}).unwrap();
}
let collection = db.collection::<Document>("config");
let doc1 = collection.find_one(doc! {
"_id": "c1",
}).unwrap().unwrap();
assert_eq!(doc1.get("value").unwrap().as_str().unwrap(), "c1");
let collection = db.collection::<Document>("config");
let doc1 = collection.find_one(doc! {
"_id": "c2",
}).unwrap().unwrap();
assert_eq!(doc1.get("value").unwrap().as_str().unwrap(), "c22");
});
}
#[test]
fn test_find() {
vec![
create_file_and_return_db_with_items("test-find", TEST_SIZE),
].iter().for_each(|db| {
let collection = db.collection::<Document>("test");
let result = collection
.find(doc! {
"content": "3",
})
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 1);
let one = result[0].clone();
assert_eq!(one.get("content").unwrap().as_str().unwrap(), "3");
});
}
#[test]
fn test_nested_range_queries() {
let db = prepare_db("test-nested-range-queries").unwrap();
let collection = db.collection::<Document>("events");
collection.insert_many(vec![
doc! {
"_id": 1,
"metadata": {
"created_at": -1,
},
},
doc! {
"_id": 2,
"metadata": {
"created_at": 0,
},
},
doc! {
"_id": 3,
"metadata": {
"created_at": 10,
},
},
doc! {
"_id": 4,
"metadata": {},
},
doc! {
"_id": 5,
"metadata": "not a document",
},
doc! {
"_id": 6,
"metadata": {
"audit": {
"created_at": 20,
},
},
},
]).unwrap();
let cases = [
(
doc! {
"metadata.created_at": {
"$gt": 0,
},
},
vec![3],
),
(
doc! {
"metadata.created_at": {
"$gte": 0,
},
},
vec![2, 3],
),
(
doc! {
"metadata.created_at": {
"$lt": 10,
},
},
vec![1, 2],
),
(
doc! {
"metadata.created_at": {
"$lte": 0,
},
},
vec![1, 2],
),
(
doc! {
"metadata.created_at": {
"$gte": 0,
"$lt": 10,
},
},
vec![2],
),
(
doc! {
"metadata.audit.created_at": {
"$gte": 20,
},
},
vec![6],
),
];
for (filter, expected_ids) in cases {
let mut actual_ids = collection
.find(filter)
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap()
.into_iter()
.map(|document| document.get_i32("_id").unwrap())
.collect::<Vec<_>>();
actual_ids.sort_unstable();
assert_eq!(actual_ids, expected_ids);
}
}
#[test]
fn test_nested_datetime_range_query() {
let db = prepare_db("test-nested-datetime-range-query").unwrap();
let collection = db.collection::<Document>("events");
collection.insert_many(vec![
doc! {
"_id": 1,
"metadata": {
"created_at": DateTime::from_millis(-1),
},
},
doc! {
"_id": 2,
"metadata": {
"created_at": DateTime::from_millis(10),
},
},
]).unwrap();
let result = collection
.find(doc! {
"metadata.created_at": {
"$gte": DateTime::from_millis(0),
},
})
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].get_i32("_id").unwrap(), 2);
}
#[test]
fn test_nested_range_queries_in_update_and_delete() {
let db = prepare_db("test-nested-range-queries-in-update-and-delete").unwrap();
let collection = db.collection::<Document>("events");
collection.insert_many(vec![
doc! {
"_id": 1,
"metadata": {
"created_at": 1,
},
"status": "old",
},
doc! {
"_id": 2,
"metadata": {
"created_at": 20,
},
"status": "old",
},
]).unwrap();
let update_result = collection.update_one(
doc! {
"metadata.created_at": {
"$gte": 20,
},
},
doc! {
"$set": {
"status": "new",
},
},
).unwrap();
assert_eq!(update_result.matched_count, 1);
assert_eq!(update_result.modified_count, 1);
assert_eq!(
collection.find_one(doc! {
"_id": 2,
}).unwrap().unwrap().get_str("status").unwrap(),
"new",
);
let delete_result = collection.delete_one(doc! {
"metadata.created_at": {
"$lt": 10,
},
}).unwrap();
assert_eq!(delete_result.deleted_count, 1);
assert_eq!(collection.count_documents().unwrap(), 1);
assert!(collection.find_one(doc! {
"_id": 1,
}).unwrap().is_none());
}
#[test]
fn test_find_empty_collection() {
let db = prepare_db("test-find-empty-collection").unwrap();
{
let collection = db.collection::<Document>("test");
let mut cursor = collection.find(doc! {}).run().unwrap();
assert!(!cursor.advance().unwrap());
}
let txn = db.start_transaction().unwrap();
let collection = txn.collection::<Document>("test");
let mut cursor = collection.find(doc! {}).run().unwrap();
assert!(!cursor.advance().unwrap());
}
#[test]
fn test_find_with_empty_document() {
vec![
prepare_db("test-find-with-empty-document").unwrap(),
].iter().for_each(|db| {
let fruits = db.collection::<Document>("fruits");
fruits.insert_many(vec![
doc! {
"name": "apple",
"color": "red",
"shape": "round",
},
doc! {
"name": "banana",
"color": "yellow",
"shape": "long",
},
doc! {
"name": "orange",
"color": "orange",
"shape": "round",
},
]).unwrap();
let result = fruits
.find(doc! {})
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 3);
});
}
#[test]
fn test_not_expression() {
vec![
prepare_db("test-not-expression").unwrap(),
].iter().for_each(|db| {
let metrics = db.metrics();
metrics.enable();
let col = db.collection::<Document>("teacher");
col.insert_many(vec![
doc! {
"name": "David",
"age": 33,
},
doc! {
"name": "John",
"age": 22,
},
doc! {
"name": "Mary",
"age": 18,
},
doc! {
"name": "Peter",
"age": 18,
},
]).unwrap();
let result = col
.find(doc! {
"age": {
"$not": {
"$eq": 18,
},
},
})
.run()
.unwrap()
.collect::<Result<Vec<Document>>>().unwrap();
assert_eq!(result.len(), 2);
assert_eq!(result[0].get("name").unwrap().as_str().unwrap(), "David");
assert_eq!(result[1].get("name").unwrap().as_str().unwrap(), "John");
});
}
#[test]
fn test_find_skip() {
let db = prepare_db("test-find-skip").unwrap();
let fruits = db.collection::<Document>("fruits");
fruits.insert_many(vec![
doc! {
"name": "apple",
"color": "red",
"shape": "round",
},
doc! {
"name": "banana",
"color": "yellow",
"shape": "long",
},
doc! {
"name": "orange",
"color": "orange",
"shape": "round",
},
doc! {
"name": "grape",
"color": "purple",
"shape": "round",
},
doc! {
"name": "watermelon",
"color": "green",
"shape": "round",
},
]).unwrap();
let result = fruits
.find(doc! {})
.skip(2)
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 3);
}
#[test]
fn test_find_limit() {
let db = prepare_db("test-find-limit").unwrap();
let fruits = db.collection::<Document>("fruits");
fruits.insert_many(vec![
doc! {
"name": "apple",
"color": "red",
"shape": "round",
},
doc! {
"name": "banana",
"color": "yellow",
"shape": "long",
},
doc! {
"name": "orange",
"color": "orange",
"shape": "round",
},
doc! {
"name": "grape",
"color": "purple",
"shape": "round",
},
doc! {
"name": "watermelon",
"color": "green",
"shape": "round",
},
]).unwrap();
let result = fruits
.find(doc! {})
.limit(3)
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 3);
assert_eq!(result[0].get("name").unwrap().as_str().unwrap(), "apple");
assert_eq!(result[1].get("name").unwrap().as_str().unwrap(), "banana");
assert_eq!(result[2].get("name").unwrap().as_str().unwrap(), "orange");
let result = fruits
.find(doc! {})
.skip(2)
.limit(2)
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 2);
assert_eq!(result[0].get("name").unwrap().as_str().unwrap(), "orange");
}
#[test]
fn test_find_sort() {
let db = prepare_db("test-find-sort").unwrap();
let fruits = db.collection::<Document>("fruits");
fruits.insert_many(vec![
doc! {
"name": "apple",
"color": "red",
"shape": "round",
"weight": 1,
},
doc! {
"name": "banana",
"color": "yellow",
"shape": "long",
"weight": 2,
},
doc! {
"name": "orange",
"color": "orange",
"shape": "round",
"weight": 3,
},
doc! {
"name": "grape",
"color": "purple",
"shape": "round",
"weight": 4,
},
doc! {
"name": "watermelon",
"color": "green",
"shape": "round",
"weight": 5,
},
]).unwrap();
let result = fruits
.find(doc! {})
.sort(doc! {
"weight": 1,
})
.run()
.unwrap()
.collect::<Result<Vec<Document>>>()
.unwrap();
assert_eq!(result.len(), 5);
assert_eq!(result[0].get("name").unwrap().as_str().unwrap(), "apple");
assert_eq!(result[1].get("name").unwrap().as_str().unwrap(), "banana");
assert_eq!(result[2].get("name").unwrap().as_str().unwrap(), "orange");
}