green_barrel/models/db_query_api/commons.rs
1//! Common query methods.
2
3use async_trait::async_trait;
4use futures::stream::StreamExt;
5use mongodb::{
6 bson::{doc, document::Document, Bson},
7 options::{
8 AggregateOptions, CountOptions, CreateIndexOptions, DeleteOptions, DistinctOptions,
9 DropCollectionOptions, DropIndexOptions, EstimatedDocumentCountOptions,
10 FindOneAndDeleteOptions, FindOneOptions, FindOptions,
11 },
12 results::{CreateIndexResult, CreateIndexesResult},
13 Client, IndexModel, Namespace,
14};
15use serde::{de::DeserializeOwned, ser::Serialize};
16use std::error::Error;
17
18use crate::{
19 models::{caching::Caching, converters::Converters, output_data::OutputData, Main},
20 store::METADATA,
21};
22
23/// Common query methods.
24#[async_trait(?Send)]
25pub trait QCommons: Main + Caching + Converters {
26 /// Creates the given index on this collection.
27 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.create_index
28 ///
29 /// # Example:
30 ///
31 /// ```
32 /// let options = IndexOptions::builder()
33 /// .unique(true)
34 /// .name("usernameIdx".to_string())
35 /// .build();
36 /// let index = IndexModel::builder()
37 /// .keys(doc! { "username": 1 })
38 /// .options(options)
39 /// .build();
40 /// let result = ModelName::create_index(&client, index, None).await;
41 /// assert!(result.is_ok());
42 /// ```
43 ///
44 async fn create_index(
45 client: &Client,
46 index: IndexModel,
47 options: impl Into<Option<CreateIndexOptions>>,
48 ) -> Result<CreateIndexResult, Box<dyn Error>>
49 where
50 Self: Serialize + DeserializeOwned + Sized,
51 {
52 let (database_name, collection_name) = {
53 // Get a key to access the metadata store.
54 let key = Self::key()?;
55 // Get metadata store.
56 let metadata = METADATA.lock().await;
57 // Get metadata of Model.
58 if let Some(meta) = metadata.get(&key) {
59 (meta.database_name.clone(), meta.collection_name.clone())
60 } else {
61 Err(format!(
62 "Model key: `{key}` ; Method: `create_index()` => \
63 Failed to get data from cache.",
64 ))?
65 }
66 };
67 Ok(client
68 .database(&database_name)
69 .collection::<Document>(&collection_name)
70 .create_index(index, options)
71 .await?)
72 }
73
74 /// Creates the given index on this collection.
75 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.create_index
76 ///
77 /// # Example:
78 ///
79 /// ```
80 /// let name = "usernameIdx";
81 /// let result = ModelName::drop_index(&client, name, None).await;
82 /// assert!(result.is_ok());
83 /// ```
84 ///
85 async fn drop_index(
86 client: &Client,
87 name: impl AsRef<str>,
88 options: impl Into<Option<DropIndexOptions>>,
89 ) -> Result<(), Box<dyn Error>>
90 where
91 Self: Serialize + DeserializeOwned + Sized,
92 {
93 let (database_name, collection_name) = {
94 // Get a key to access the metadata store.
95 let key = Self::key()?;
96 // Get metadata store.
97 let metadata = METADATA.lock().await;
98 // Get metadata of Model.
99 if let Some(meta) = metadata.get(&key) {
100 (meta.database_name.clone(), meta.collection_name.clone())
101 } else {
102 Err(format!(
103 "Model key: `{key}` ; Method: `drop_index()` => \
104 Failed to get data from cache.",
105 ))?
106 }
107 };
108 Ok(client
109 .database(&database_name)
110 .collection::<Document>(&collection_name)
111 .drop_index(name, options)
112 .await?)
113 }
114
115 /// Creates the given indexes on this collection.
116 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.create_indexes
117 ///
118 /// # Example:
119 ///
120 /// ```
121 /// let username_idx_options = IndexOptions::builder()
122 /// .unique(true)
123 /// .name("usernameIdx".to_string())
124 /// .build();
125 /// let indexes = [IndexModel::builder()
126 /// .keys(doc! { "username": 1 })
127 /// .options(username_idx_options)
128 /// .build()];
129 /// let result = ModelName::create_indexes(&client, indexes, None).await;
130 /// assert!(result.is_ok());
131 /// ```
132 ///
133 async fn create_indexes(
134 client: &Client,
135 indexes: impl IntoIterator<Item = IndexModel>,
136 options: impl Into<Option<CreateIndexOptions>>,
137 ) -> Result<CreateIndexesResult, Box<dyn Error>>
138 where
139 Self: Serialize + DeserializeOwned + Sized,
140 {
141 let (database_name, collection_name) = {
142 // Get a key to access the metadata store.
143 let key = Self::key()?;
144 // Get metadata store.
145 let metadata = METADATA.lock().await;
146 // Get metadata of Model.
147 if let Some(meta) = metadata.get(&key) {
148 (meta.database_name.clone(), meta.collection_name.clone())
149 } else {
150 Err(format!(
151 "Model key: `{key}` ; Method: `create_indexes()` => \
152 Failed to get data from cache.",
153 ))?
154 }
155 };
156 Ok(client
157 .database(&database_name)
158 .collection::<Document>(&collection_name)
159 .create_indexes(indexes, options)
160 .await?)
161 }
162
163 /// Drops all indexes associated with this collection.
164 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.drop_indexes
165 ///
166 /// # Example:
167 ///
168 /// ```
169 /// let result = ModelName::drop_indexes(&client, None).await;
170 /// assert!(result.is_ok());
171 /// ```
172 ///
173 async fn drop_indexes(
174 client: &Client,
175 options: impl Into<Option<DropIndexOptions>>,
176 ) -> Result<(), Box<dyn Error>>
177 where
178 Self: Serialize + DeserializeOwned + Sized,
179 {
180 let (database_name, collection_name) = {
181 // Get a key to access the metadata store.
182 let key = Self::key()?;
183 // Get metadata store.
184 let metadata = METADATA.lock().await;
185 // Get metadata of Model.
186 if let Some(meta) = metadata.get(&key) {
187 (meta.database_name.clone(), meta.collection_name.clone())
188 } else {
189 Err(format!(
190 "Model key: `{key}` ; Method: `drop_indexes()` => \
191 Failed to get data from cache.",
192 ))?
193 }
194 };
195 Ok(client
196 .database(&database_name)
197 .collection::<Document>(&collection_name)
198 .drop_indexes(options)
199 .await?)
200 }
201
202 /// Runs an aggregation operation.
203 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.aggregate
204 ///
205 /// # Example:
206 ///
207 /// ```
208 /// use mongodb::bson::doc;
209 ///
210 /// let pipeline = vec![doc! {}];
211 /// let doc_list = ModelName::aggregate(&client, pipeline, None).await?;
212 /// println!("{:?}", doc_list);
213 /// ```
214 ///
215 async fn aggregate(
216 client: &Client,
217 pipeline: Vec<Document>,
218 options: Option<AggregateOptions>,
219 ) -> Result<Vec<Document>, Box<dyn Error>>
220 where
221 Self: Serialize + DeserializeOwned + Sized,
222 {
223 let (database_name, collection_name) = {
224 // Get a key to access the metadata store.
225 let key = Self::key()?;
226 // Get metadata store.
227 let metadata = METADATA.lock().await;
228 // Get metadata of Model.
229 if let Some(meta) = metadata.get(&key) {
230 (meta.database_name.clone(), meta.collection_name.clone())
231 } else {
232 Err(format!(
233 "Model key: `{key}` ; Method: `aggregate()` => \
234 Failed to get data from cache.",
235 ))?
236 }
237 };
238 // Access collection.
239 let coll = client
240 .database(database_name.as_str())
241 .collection::<Document>(collection_name.as_str());
242 // Execute query.
243 Ok(coll
244 .aggregate(pipeline, options)
245 .await?
246 .map(|item| item.unwrap())
247 .collect()
248 .await)
249 }
250
251 /// Gets the number of documents matching filter.
252 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.count_documents
253 ///
254 /// # Example:
255 ///
256 /// ```
257 /// use mongodb::bson::doc;
258 ///
259 /// let filter = doc!{};
260 /// let count = ModelName::count_documents &client, Some(filter), None).await?;
261 /// println!("{}", count);
262 /// ```
263 ///
264 async fn count_documents(
265 client: &Client,
266 filter: Option<Document>,
267 options: Option<CountOptions>,
268 ) -> Result<u64, Box<dyn Error>>
269 where
270 Self: Serialize + DeserializeOwned + Sized,
271 {
272 let (database_name, collection_name) = {
273 // Get a key to access the metadata store.
274 let key = Self::key()?;
275 // Get metadata store.
276 let metadata = METADATA.lock().await;
277 // Get metadata of Model.
278 if let Some(meta) = metadata.get(&key) {
279 (meta.database_name.clone(), meta.collection_name.clone())
280 } else {
281 Err(format!(
282 "Model key: `{key}` ; Method: `count_documents()` => \
283 Failed to get data from cache.",
284 ))?
285 }
286 };
287 // Access collection.
288 let coll = client
289 .database(database_name.as_str())
290 .collection::<Document>(collection_name.as_str());
291 // Execute query.
292 Ok(coll.count_documents(filter, options).await?)
293 }
294
295 /// Deletes all documents stored in the collection matching query.
296 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.delete_many
297 ///
298 /// # Example:
299 ///
300 /// ```
301 /// use mongodb::bson::doc;
302 ///
303 /// let query = doc!{};
304 /// let output_data = ModelName::delete_many(&client, query, None).await?;
305 /// if !output_data.is_valid() {
306 /// println!("{}", output_data.err_msg());
307 /// }
308 /// ```
309 ///
310 async fn delete_many(
311 client: &Client,
312 query: Document,
313 options: Option<DeleteOptions>,
314 ) -> Result<OutputData, Box<dyn Error>>
315 where
316 Self: Serialize + DeserializeOwned + Sized,
317 {
318 let (database_name, collection_name, is_del_doc) = {
319 // Get a key to access the metadata store.
320 let key = Self::key()?;
321 // Get metadata store.
322 let metadata = METADATA.lock().await;
323 // Get metadata of Model.
324 if let Some(meta) = metadata.get(&key) {
325 (
326 meta.database_name.clone(),
327 meta.collection_name.clone(),
328 meta.is_del_doc,
329 )
330 } else {
331 Err(format!(
332 "Model key: `{key}` ; Method: `delete_many()` => \
333 Failed to get data from cache.",
334 ))?
335 }
336 };
337 // Get permission to delete the document.
338 let is_permission_delete: bool = is_del_doc;
339 // Error message for the client.
340 // (Main use for admin panel.)
341 let err_msg = if is_permission_delete {
342 String::new()
343 } else {
344 "It is forbidden to perform delete.".to_string()
345 };
346 //
347 let mut deleted_count = 0;
348 let result_bool = if is_permission_delete {
349 // Access collection.
350 let coll = client
351 .database(database_name.as_str())
352 .collection::<Document>(collection_name.as_str());
353 // Execute query.
354 deleted_count = coll.delete_many(query, options).await?.deleted_count;
355 true
356 } else {
357 false
358 };
359 Ok(OutputData::Delete((result_bool, err_msg, deleted_count)))
360 }
361
362 /// Deletes up to one document found matching query.
363 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.delete_one
364 ///
365 /// # Example:
366 ///
367 /// ```
368 /// use mongodb::bson::doc;
369 ///
370 /// let query = doc!{};
371 /// let output_data = ModelName::delete_one(&client, query, None).await?;
372 /// if !output_data.is_valid() {
373 /// println!("{}", output_data.err_msg());
374 /// }
375 /// ```
376 ///
377 async fn delete_one(
378 client: &Client,
379 query: Document,
380 options: Option<DeleteOptions>,
381 ) -> Result<OutputData, Box<dyn Error>>
382 where
383 Self: Serialize + DeserializeOwned + Sized,
384 {
385 let (database_name, collection_name, is_del_doc) = {
386 // Get a key to access the metadata store.
387 let key = Self::key()?;
388 // Get metadata store.
389 let metadata = METADATA.lock().await;
390 // Get metadata of Model.
391 if let Some(meta) = metadata.get(&key) {
392 (
393 meta.database_name.clone(),
394 meta.collection_name.clone(),
395 meta.is_del_doc,
396 )
397 } else {
398 Err(format!(
399 "Model key: `{key}` ; Method: `delete_one()` => \
400 Failed to get data from cache.",
401 ))?
402 }
403 };
404 // Get permission to delete the document.
405 let is_permission_delete: bool = is_del_doc;
406 // Error message for the client.
407 // (Main use for admin panel.)
408 let err_msg = if is_permission_delete {
409 String::new()
410 } else {
411 "It is forbidden to perform delete.".to_string()
412 };
413 //
414 let mut deleted_count = 0;
415 let result_bool = if is_permission_delete {
416 // Access collection.
417 let coll = client
418 .database(database_name.as_str())
419 .collection::<Document>(collection_name.as_str());
420 // Execute query.
421 deleted_count = coll.delete_one(query, options).await?.deleted_count;
422 true
423 } else {
424 false
425 };
426 Ok(OutputData::Delete((result_bool, err_msg, deleted_count)))
427 }
428
429 /// Finds the distinct values of the field specified by field_name across the collection.
430 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.distinct
431 ///
432 /// # Example:
433 ///
434 /// ```
435 /// use mongodb::bson::doc;
436 ///
437 /// let field_name = "";
438 /// let filter = doc!{};
439 /// let output_data = ModelName::distinct(&client, field_name, Some(filter), None).await?;
440 /// println!("{:?}", output_data);
441 /// ```
442 ///
443 async fn distinct(
444 client: &Client,
445 field_name: &str,
446 filter: Option<Document>,
447 options: Option<DistinctOptions>,
448 ) -> Result<Vec<Bson>, Box<dyn Error>>
449 where
450 Self: Serialize + DeserializeOwned + Sized,
451 {
452 let (database_name, collection_name) = {
453 // Get a key to access the metadata store.
454 let key = Self::key()?;
455 // Get metadata store.
456 let metadata = METADATA.lock().await;
457 // Get metadata of Model.
458 if let Some(meta) = metadata.get(&key) {
459 (meta.database_name.clone(), meta.collection_name.clone())
460 } else {
461 Err(format!(
462 "Model key: `{key}` ; Method: `distinct()` => \
463 Failed to get data from cache.",
464 ))?
465 }
466 };
467 // Access collection.
468 let coll = client
469 .database(database_name.as_str())
470 .collection::<Document>(collection_name.as_str());
471 // Execute query.
472 Ok(coll.distinct(field_name, filter, options).await?)
473 }
474
475 /// Drops the collection, deleting all data and indexes stored in it.
476 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.drop
477 ///
478 /// # Example:
479 ///
480 /// ```
481 /// let output_data = ModelName::drop &client, None).await?;
482 /// if !output_data.is_valid() {
483 /// println!("{}", output_data.err_msg());
484 /// }
485 /// ```
486 ///
487 async fn drop(
488 client: &Client,
489 options: Option<DropCollectionOptions>,
490 ) -> Result<OutputData, Box<dyn Error>>
491 where
492 Self: Serialize + DeserializeOwned + Sized,
493 {
494 let (database_name, collection_name, is_del_doc) = {
495 // Get a key to access the metadata store.
496 let key = Self::key()?;
497 // Get metadata store.
498 let metadata = METADATA.lock().await;
499 // Get metadata of Model.
500 if let Some(meta) = metadata.get(&key) {
501 (
502 meta.database_name.clone(),
503 meta.collection_name.clone(),
504 meta.is_del_doc,
505 )
506 } else {
507 Err(format!(
508 "Model key: `{key}` ; Method: `drop()` => \
509 Failed to get data from cache.",
510 ))?
511 }
512 };
513 // Get permission to delete the document.
514 let is_permission_delete: bool = is_del_doc;
515 //
516 let err_msg = if is_permission_delete {
517 String::new()
518 } else {
519 "It is forbidden to perform delete.".to_string()
520 };
521 // Get a logical result.
522 let result_bool = if is_permission_delete {
523 // Access collection.
524 let coll = client
525 .database(database_name.as_str())
526 .collection::<Document>(collection_name.as_str());
527 // Execute query.
528 coll.drop(options).await.is_ok()
529 } else {
530 false
531 };
532 let deleted_count = u64::from(result_bool);
533 Ok(OutputData::Delete((result_bool, err_msg, deleted_count)))
534 }
535
536 /// Estimates the number of documents in the collection using collection metadata.
537 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.estimated_document_count
538 ///
539 /// # Example:
540 ///
541 /// ```
542 /// let count = ModelName::estimated_document_count &client, None).await?;
543 /// println!("{}", count);
544 /// ```
545 ///
546 async fn estimated_document_count(
547 client: &Client,
548 options: Option<EstimatedDocumentCountOptions>,
549 ) -> Result<u64, Box<dyn Error>>
550 where
551 Self: Serialize + DeserializeOwned + Sized,
552 {
553 let (database_name, collection_name) = {
554 // Get a key to access the metadata store.
555 let key = Self::key()?;
556 // Get metadata store.
557 let metadata = METADATA.lock().await;
558 // Get metadata of Model.
559 if let Some(meta) = metadata.get(&key) {
560 (meta.database_name.clone(), meta.collection_name.clone())
561 } else {
562 Err(format!(
563 "Model key: `{key}` ; Method: `estimated_document_count()` => \
564 Failed to get data from cache.",
565 ))?
566 }
567 };
568 // Access collection.
569 let coll = client
570 .database(database_name.as_str())
571 .collection::<Document>(collection_name.as_str());
572 // Execute query.
573 Ok(coll.estimated_document_count(options).await?)
574 }
575
576 /// Finds the documents in the collection matching filter and
577 /// return document list ( missing fields type ).
578 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find
579 ///
580 /// # Example:
581 ///
582 /// ```
583 /// let result = ModelName::find_many_to_doc_list &client, None, None).await?;
584 /// if let Some(doc_list) = result {
585 /// println!("{:?}", doc_list);
586 /// }
587 /// ```
588 ///
589 async fn find_many_to_doc_list(
590 client: &Client,
591 filter: Option<Document>,
592 options: Option<FindOptions>,
593 ) -> Result<Option<Vec<Document>>, Box<dyn Error>>
594 where
595 Self: Serialize + DeserializeOwned + Sized,
596 {
597 let (database_name, collection_name, db_query_docs_limit) = {
598 // Get a key to access the metadata store.
599 let key = Self::key()?;
600 // Get metadata store.
601 let metadata = METADATA.lock().await;
602 // Get metadata of Model.
603 if let Some(meta) = metadata.get(&key) {
604 (
605 meta.database_name.clone(),
606 meta.collection_name.clone(),
607 meta.db_query_docs_limit,
608 )
609 } else {
610 Err(format!(
611 "Model key: `{key}` ; Method: `find_many_to_doc_list()` => \
612 Failed to get data from cache.",
613 ))?
614 }
615 };
616 // Access collection
617 let coll = client
618 .database(database_name.as_str())
619 .collection::<Document>(collection_name.as_str());
620 // Apply parameter `db_query_docs_limit`.
621 // (if necessary)
622 let options = if let Some(mut options) = options {
623 if options.limit == Some(0) {
624 options.limit = Some(db_query_docs_limit as i64);
625 }
626 options
627 } else {
628 FindOptions::builder()
629 .limit(Some(db_query_docs_limit as i64))
630 .build()
631 };
632 // Execute query.
633 let doc_list = Self::many_to_doc_list(filter, Some(options), coll).await?;
634 if doc_list.is_empty() {
635 return Ok(None);
636 }
637 Ok(Some(doc_list))
638 }
639
640 /// Finds the documents in the collection matching filter and
641 /// return in JSON format ( missing fields type ).
642 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find
643 ///
644 /// # Example:
645 ///
646 /// ```
647 /// let result = ModelName::find_many_to_json &client, None, None).await?;
648 /// if let Some(json_line) = result {
649 /// println!("{}", json_line);
650 /// }
651 /// ```
652 ///
653 async fn find_many_to_json(
654 client: &Client,
655 filter: Option<Document>,
656 options: Option<FindOptions>,
657 ) -> Result<Option<String>, Box<dyn Error>>
658 where
659 Self: Serialize + DeserializeOwned + Sized,
660 {
661 let (
662 database_name,
663 collection_name,
664 db_query_docs_limit,
665 ignore_fields,
666 field_type_map,
667 model_name,
668 ) = {
669 // Get a key to access the metadata store.
670 let key = Self::key()?;
671 // Get metadata store.
672 let metadata = METADATA.lock().await;
673 // Get metadata of Model.
674 if let Some(meta) = metadata.get(&key) {
675 (
676 meta.database_name.clone(),
677 meta.collection_name.clone(),
678 meta.db_query_docs_limit,
679 meta.ignore_fields.clone(),
680 meta.field_type_map.clone(),
681 meta.model_name.clone(),
682 )
683 } else {
684 Err(format!(
685 "Model key: `{key}` ; Method: `find_many_to_json()` => \
686 Failed to get data from cache.",
687 ))?
688 }
689 };
690 // Access collection
691 let coll = client
692 .database(database_name.as_str())
693 .collection::<Document>(collection_name.as_str());
694 // Apply parameter `db_query_docs_limit`.
695 // (if necessary)
696 let options = if let Some(mut options) = options {
697 if options.limit == Some(0) {
698 options.limit = Some(db_query_docs_limit as i64);
699 }
700 options
701 } else {
702 FindOptions::builder()
703 .limit(Some(db_query_docs_limit as i64))
704 .build()
705 };
706 // Execute query.
707 Self::many_to_json(
708 filter,
709 Some(options),
710 coll,
711 &ignore_fields,
712 &field_type_map,
713 model_name.as_str(),
714 )
715 .await
716 }
717
718 /// Finds a single document in the collection matching filter and
719 /// return in Doc format ( missing fields type ).
720 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find_one
721 ///
722 /// # Example:
723 ///
724 /// ```
725 /// use mongodb::bson::doc;
726 /// let filter = doc!{"username": "user_1"};
727 /// let result = ModelName::find_one_to_doc(&client, filter, None).await?;
728 /// if let Some(doc) = result {
729 /// println!("{:?}", doc);
730 /// }
731 /// ```
732 ///
733 async fn find_one_to_doc(
734 client: &Client,
735 filter: Document,
736 options: Option<FindOneOptions>,
737 ) -> Result<Option<Document>, Box<dyn Error>>
738 where
739 Self: Serialize + DeserializeOwned + Sized,
740 {
741 let (database_name, collection_name) = {
742 // Get a key to access the metadata store.
743 let key = Self::key()?;
744 // Get metadata store.
745 let metadata = METADATA.lock().await;
746 // Get metadata of Model.
747 if let Some(meta) = metadata.get(&key) {
748 (meta.database_name.clone(), meta.collection_name.clone())
749 } else {
750 Err(format!(
751 "Model key: `{key}` ; Method: `find_one_to_doc()` => \
752 Failed to get data from cache.",
753 ))?
754 }
755 };
756 // Access collection.
757 let coll = client
758 .database(database_name.as_str())
759 .collection::<Document>(collection_name.as_str());
760 // Execute query.
761 Ok(coll.find_one(filter, options).await?)
762 }
763
764 /// Finds a single document in the collection matching filter and
765 /// return in JSON format.
766 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find_one
767 ///
768 /// # Example:
769 ///
770 /// ```
771 /// use mongodb::bson::doc;
772 /// let filter = doc!{"username": "user_1"};
773 /// let json = ModelName::find_one_to_json(&client, filter, None).await?;
774 /// println!("{}", json);
775 /// ```
776 ///
777 async fn find_one_to_json(
778 client: &Client,
779 filter: Document,
780 options: Option<FindOneOptions>,
781 ) -> Result<String, Box<dyn Error>>
782 where
783 Self: Serialize + DeserializeOwned + Sized,
784 {
785 let (
786 database_name,
787 collection_name,
788 ignore_fields,
789 field_type_map,
790 model_name,
791 model_json,
792 fields_name,
793 ) = {
794 // Get a key to access the metadata store.
795 let key = Self::key()?;
796 // Get metadata store.
797 let metadata = METADATA.lock().await;
798 // Get metadata of Model.
799 if let Some(meta) = metadata.get(&key) {
800 (
801 meta.database_name.clone(),
802 meta.collection_name.clone(),
803 meta.ignore_fields.clone(),
804 meta.field_type_map.clone(),
805 meta.model_name.clone(),
806 meta.model_json.clone(),
807 meta.fields_name.clone(),
808 )
809 } else {
810 Err(format!(
811 "Model key: `{key}` ; Method: `find_one_to_json()` => \
812 Failed to get data from cache.",
813 ))?
814 }
815 };
816 // Access collection.
817 let coll = client
818 .database(database_name.as_str())
819 .collection::<Document>(collection_name.as_str());
820 // Get document from database and convert to model instance in jsob-line format.
821 if let Ok(Some(db_doc)) = coll.find_one(filter, options).await {
822 let mut model_json = model_json.clone();
823 Self::one_to_json_val(
824 db_doc,
825 &ignore_fields,
826 &field_type_map,
827 &model_name,
828 &fields_name,
829 &mut model_json,
830 )?;
831 return Ok(serde_json::to_string(&model_json)?);
832 }
833 //
834 Ok(String::new())
835 }
836
837 /// Finds a single document in the collection matching filter and
838 /// return as model instance.
839 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find_one
840 ///
841 /// # Example:
842 ///
843 /// ```
844 /// use mongodb::bson::doc;
845 /// let filter = doc!{"username": "user_1"};
846 /// let result = ModelName::find_one_to_instance(&client, filter, None).await?;
847 /// if let Some(instance) = result {
848 /// println!("{:?}", instance);
849 /// }
850 /// ```
851 ///
852 async fn find_one_to_instance(
853 client: &Client,
854 filter: Document,
855 options: Option<FindOneOptions>,
856 ) -> Result<Option<Self>, Box<dyn Error>>
857 where
858 Self: Serialize + DeserializeOwned + Sized,
859 {
860 let (
861 database_name,
862 collection_name,
863 ignore_fields,
864 field_type_map,
865 model_name,
866 model_json,
867 fields_name,
868 ) = {
869 // Get a key to access the metadata store.
870 let key = Self::key()?;
871 // Get metadata store.
872 let metadata = METADATA.lock().await;
873 // Get metadata of Model.
874 if let Some(meta) = metadata.get(&key) {
875 (
876 meta.database_name.clone(),
877 meta.collection_name.clone(),
878 meta.ignore_fields.clone(),
879 meta.field_type_map.clone(),
880 meta.model_name.clone(),
881 meta.model_json.clone(),
882 meta.fields_name.clone(),
883 )
884 } else {
885 Err(format!(
886 "Model key: `{key}` ; Method: `find_one_to_instance()` => \
887 Failed to get data from cache.",
888 ))?
889 }
890 };
891 // Access collection.
892 let coll = client
893 .database(database_name.as_str())
894 .collection::<Document>(collection_name.as_str());
895 // Get document from database and convert to model instance.
896 if let Ok(Some(db_doc)) = coll.find_one(filter, options).await {
897 let mut model_json = model_json.clone();
898 Self::one_to_json_val(
899 db_doc,
900 &ignore_fields,
901 &field_type_map,
902 &model_name,
903 &fields_name,
904 &mut model_json,
905 )?;
906 return Ok(Some(serde_json::from_value(model_json)?));
907 }
908 //
909 Ok(None)
910 }
911
912 /// Atomically finds up to one document in the collection matching filter and
913 /// deletes it ( missing fields type ).
914 /// Returns the deleted document (in Doc format).
915 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find_one_and_delete
916 ///
917 /// # Example:
918 ///
919 /// ```
920 /// ```
921 /// use mongodb::bson::doc;
922 /// let filter = doc!{"username": "user_1"};
923 /// let result = ModelName::find_one_and_delete(&client, filter, None).await?;
924 /// if let Some(doc) = result) {
925 /// println!("{:?}", doc);
926 /// }
927 /// ```
928 ///
929 async fn find_one_and_delete(
930 client: &Client,
931 filter: Document,
932 options: Option<FindOneAndDeleteOptions>,
933 ) -> Result<Option<Document>, Box<dyn Error>>
934 where
935 Self: Serialize + DeserializeOwned + Sized,
936 {
937 let (database_name, collection_name, is_del_doc) = {
938 // Get a key to access the metadata store.
939 let key = Self::key()?;
940 // Get metadata store.
941 let metadata = METADATA.lock().await;
942 // Get metadata of Model.
943 if let Some(meta) = metadata.get(&key) {
944 (
945 meta.database_name.clone(),
946 meta.collection_name.clone(),
947 meta.is_del_doc,
948 )
949 } else {
950 Err(format!(
951 "Model key: `{key}` ; Method: `find_one_and_delete()` => \
952 Failed to get data from cache.",
953 ))?
954 }
955 };
956 // Get permission to delete the document.
957 let is_permission_delete: bool = is_del_doc;
958 //
959 if !is_permission_delete {
960 Err("It is forbidden to perform delete.".to_string())?
961 }
962 // Access collection.
963 let coll = client
964 .database(database_name.as_str())
965 .collection::<Document>(collection_name.as_str());
966 // Execute query.
967 Ok(coll.find_one_and_delete(filter, options).await?)
968 }
969
970 /// Gets the name of the Collection.
971 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.name
972 ///
973 /// # Example:
974 ///
975 /// ```
976 /// let name = ModelName::name &client).await?;
977 /// println!("{}", name);
978 /// ```
979 ///
980 async fn collection_name(client: &Client) -> Result<String, Box<dyn Error>>
981 where
982 Self: Serialize + DeserializeOwned + Sized,
983 {
984 let (database_name, collection_name) = {
985 // Get a key to access the metadata store.
986 let key = Self::key()?;
987 // Get metadata store.
988 let metadata = METADATA.lock().await;
989 // Get metadata of Model.
990 if let Some(meta) = metadata.get(&key) {
991 (meta.database_name.clone(), meta.collection_name.clone())
992 } else {
993 Err(format!(
994 "Model key: `{key}` ; Method: `collection_name()` => \
995 Failed to get data from cache.",
996 ))?
997 }
998 };
999 // Access collection.
1000 let coll = client
1001 .database(database_name.as_str())
1002 .collection::<Document>(collection_name.as_str());
1003 // Execute query.
1004 Ok(coll.name().to_string())
1005 }
1006
1007 /// Gets the namespace of the Collection.
1008 /// https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.namespace
1009 ///
1010 /// # Example:
1011 ///
1012 /// ```
1013 /// let name = ModelName::namespace &client).await?;
1014 /// println!("{:?}", name);
1015 /// ```
1016 ///
1017 async fn namespace(client: &Client) -> Result<Namespace, Box<dyn Error>>
1018 where
1019 Self: Serialize + DeserializeOwned + Sized,
1020 {
1021 let (database_name, collection_name) = {
1022 // Get a key to access the metadata store.
1023 let key = Self::key()?;
1024 // Get metadata store.
1025 let metadata = METADATA.lock().await;
1026 // Get metadata of Model.
1027 if let Some(meta) = metadata.get(&key) {
1028 (meta.database_name.clone(), meta.collection_name.clone())
1029 } else {
1030 Err(format!(
1031 "Model key: `{key}` ; Method: `namespace()` => \
1032 Failed to get data from cache.",
1033 ))?
1034 }
1035 };
1036 // Access collection.
1037 let coll = client
1038 .database(database_name.as_str())
1039 .collection::<Document>(collection_name.as_str());
1040 // Execute query.
1041 Ok(coll.namespace())
1042 }
1043}