tauri_plugin_mongoose/db/
documents.rs1use mongodb::{bson::{oid::ObjectId, Document}, options::{FindOptions as MongoFindOptions, FindOneOptions as MongoFindOneOptions}};
2use serde_json::Value;
3use serde::Deserialize;
4use futures::stream::TryStreamExt;
5use crate::db::state::{get_client, get_db_name};
6
7#[derive(Debug, Deserialize)]
8pub struct SearchOptions {
9 pub skip: Option<u64>,
10 pub limit: Option<i64>,
11 pub page: Option<u64>,
12 pub sort: Option<Value>,
13}
14
15pub async fn create_document(collection_name: String, document: Value) -> Result<Value, String> {
16 let client = get_client().await?;
17 let db_name = get_db_name().await;
18
19 let db = client.database(&db_name);
20 let collection = db.collection::<Document>(&collection_name);
21
22 let mut bson_doc = mongodb::bson::to_document(&document).map_err(|e| e.to_string())?;
23
24 if !bson_doc.contains_key("_id") {
25 bson_doc.insert("_id", ObjectId::new());
26 }
27
28 collection.insert_one(bson_doc.clone(), None).await.map_err(|e| e.to_string())?;
29
30 let json_doc: Value = mongodb::bson::from_document(bson_doc).map_err(|e| e.to_string())?;
31 Ok(json_doc)
32}
33
34pub async fn get_document_by_id(collection_name: String, id: String) -> Result<Option<Value>, String> {
35 let client = get_client().await?;
36 let db_name = get_db_name().await;
37
38 let db = client.database(&db_name);
39 let collection = db.collection::<Document>(&collection_name);
40
41 let oid = ObjectId::parse_str(&id).map_err(|e| format!("Invalid ID format: {}", e))?;
42 let filter = mongodb::bson::doc! { "_id": oid };
43
44 let result = collection.find_one(filter, None).await.map_err(|e| e.to_string())?;
45
46 match result {
47 Some(doc) => {
48 let json_doc: Value = mongodb::bson::from_document(doc).map_err(|e| e.to_string())?;
49 Ok(Some(json_doc))
50 },
51 None => Ok(None)
52 }
53}
54
55pub async fn find_documents(collection_name: String, filter: Option<Value>, options: Option<SearchOptions>) -> Result<Vec<Value>, String> {
56 let client = get_client().await?;
57 let db_name = get_db_name().await;
58
59 let db = client.database(&db_name);
60 let collection = db.collection::<Document>(&collection_name);
61
62 let mut find_options = MongoFindOptions::builder().build();
63
64 if let Some(opts) = options {
65 if let Some(limit) = opts.limit {
66 find_options.limit = Some(limit);
67 }
68
69 let mut skip = opts.skip.unwrap_or(0);
70 if let Some(page) = opts.page {
71 if page > 0 {
72 let limit = opts.limit.unwrap_or(10); skip = (page as u64 - 1) * (limit as u64);
74 if find_options.limit.is_none() {
76 find_options.limit = Some(limit);
77 }
78 }
79 }
80 find_options.skip = Some(skip);
81
82 if let Some(sort) = opts.sort {
83 if let Ok(sort_doc) = mongodb::bson::to_document(&sort) {
84 find_options.sort = Some(sort_doc);
85 }
86 }
87 }
88
89 let query = if let Some(f) = filter {
90 mongodb::bson::to_document(&f).map_err(|e| e.to_string())?
91 } else {
92 mongodb::bson::doc! {}
93 };
94
95 let mut cursor = collection.find(query, find_options).await.map_err(|e| e.to_string())?;
96
97 let mut docs = Vec::new();
98 while let Some(result) = cursor.try_next().await.map_err(|e| e.to_string())? {
99 let json_doc: Value = mongodb::bson::from_document(result).map_err(|e| e.to_string())?;
100 docs.push(json_doc);
101 }
102
103 Ok(docs)
104}
105
106pub async fn find_one_document(collection_name: String, filter: Option<Value>, options: Option<SearchOptions>) -> Result<Option<Value>, String> {
107 let client = get_client().await?;
108 let db_name = get_db_name().await;
109
110 let db = client.database(&db_name);
111 let collection = db.collection::<Document>(&collection_name);
112
113 let mut find_options = MongoFindOneOptions::builder().build();
114
115 if let Some(opts) = options {
116 if let Some(skip) = opts.skip {
117 find_options.skip = Some(skip);
118 }
119
120 if let Some(sort) = opts.sort {
121 if let Ok(sort_doc) = mongodb::bson::to_document(&sort) {
122 find_options.sort = Some(sort_doc);
123 }
124 }
125 }
128
129 let query = if let Some(f) = filter {
130 mongodb::bson::to_document(&f).map_err(|e| e.to_string())?
131 } else {
132 mongodb::bson::doc! {}
133 };
134
135 let result = collection.find_one(query, find_options).await.map_err(|e| e.to_string())?;
136
137 match result {
138 Some(doc) => {
139 let json_doc: Value = mongodb::bson::from_document(doc).map_err(|e| e.to_string())?;
140 Ok(Some(json_doc))
141 },
142 None => Ok(None)
143 }
144}