semilattice_database/
lib.rs1pub mod search;
2
3mod collection;
4mod relation;
5
6use async_recursion::async_recursion;
7pub use collection::{Collection, CollectionRow};
8pub use relation::{Depend, RelationIndex};
9pub use search::{Condition, Search, SearchJoin, SearchResult};
10use versatile_data::idx_binary::AvltrieeSearch;
11pub use versatile_data::{
12 create_uuid, idx_binary, uuid_string, Activity, CustomOrderKey, CustomSort, DataOption, Field,
13 FieldName, Fields, FileMmap, IdxFile, Order, OrderKey, RowSet, Term, Uuid,
14};
15
16use std::{collections::BTreeMap, num::NonZeroI32, path::PathBuf};
17
18use hashbrown::HashMap;
19
20pub struct Database {
21 collections_dir: PathBuf,
22 collections_map: HashMap<String, NonZeroI32>,
23 collections: BTreeMap<NonZeroI32, Collection>,
24 relation: RelationIndex,
25 collection_settings: std::collections::HashMap<String, DataOption>,
26}
27impl Database {
28 pub fn new(
29 dir: PathBuf,
30 collection_settings: Option<std::collections::HashMap<String, DataOption>>,
31 relation_allocation_lot: u32,
32 ) -> Self {
33 let mut collections_dir = dir.to_path_buf();
34 collections_dir.push("collection");
35
36 let mut db = Self {
37 collections_dir,
38 collections: BTreeMap::new(),
39 collections_map: HashMap::new(),
40 relation: RelationIndex::new(&dir, relation_allocation_lot),
41 collection_settings: collection_settings.unwrap_or(std::collections::HashMap::new()),
42 };
43 if db.collections_dir.exists() {
44 let dir = db.collections_dir.read_dir().unwrap();
45 for d in dir.into_iter() {
46 let d = d.unwrap();
47 if d.file_type().unwrap().is_dir() {
48 if let Some(fname) = d.file_name().to_str() {
49 if let Some(pos) = fname.find("_") {
50 if let Ok(collection_id) = (&fname[..pos]).parse::<NonZeroI32>() {
51 let name = &fname[(pos + 1)..];
52 db.create_collection(collection_id, name, d.path());
53 }
54 }
55 }
56 }
57 }
58 }
59 db
60 }
61
62 #[async_recursion(?Send)]
63 pub async fn delete(&mut self, target: &CollectionRow) {
64 let rows: Vec<_> = self.relation.index_depend().iter_by(target).collect();
65 for relation_row in rows.into_iter() {
66 if let Some(collection_row) = self.relation.index_pend().value(relation_row).cloned() {
67 self.delete(&collection_row).await;
68 }
69 }
70 for relation_row in self
71 .relation
72 .index_pend()
73 .iter_by(target)
74 .collect::<Vec<_>>()
75 .into_iter()
76 {
77 self.relation.delete(relation_row).await;
78 }
79 if let Some(collection) = self.collection_mut(target.collection_id()) {
80 collection.delete(target.row()).await;
81 }
82 }
83}