1pub mod db_element;
2pub mod db_error;
3pub mod db_f64;
4pub mod db_id;
5pub mod db_index;
6pub mod db_key_order;
7pub mod db_key_value;
8pub mod db_type;
9pub mod db_value;
10
11mod db_search_handlers;
12mod db_value_index;
13
14use self::db_error::DbError;
15use self::db_search_handlers::DefaultHandler;
16use self::db_search_handlers::LimitHandler;
17use self::db_search_handlers::LimitOffsetHandler;
18use self::db_search_handlers::OffsetHandler;
19use self::db_search_handlers::PathHandler;
20use crate::DbId;
21use crate::DbKeyValue;
22use crate::DbValue;
23use crate::QueryResult;
24use crate::SearchQueryAlgorithm;
25use crate::StorageData;
26use crate::Transaction;
27use crate::TransactionMut;
28use crate::collections::indexed_map::DbIndexedMap;
29use crate::command::Command;
30use crate::db::db_index::DbIndexes;
31use crate::db::db_key_value::DbKeyValues;
32use crate::graph::DbGraph;
33use crate::graph::GraphIndex;
34use crate::graph_search::GraphSearch;
35use crate::graph_search::SearchControl;
36use crate::query::Query;
37use crate::query::QueryMut;
38use crate::query::query_condition::QueryCondition;
39use crate::query::query_condition::QueryConditionData;
40use crate::query::query_condition::QueryConditionLogic;
41use crate::query::query_condition::QueryConditionModifier;
42use crate::query::query_id::QueryId;
43use crate::storage::Storage;
44use crate::storage::StorageIndex;
45use crate::storage::any_storage::AnyStorage;
46use crate::storage::file_storage::FileStorage;
47use crate::storage::file_storage_memory_mapped::FileStorageMemoryMapped;
48use crate::storage::memory_storage::MemoryStorage;
49use crate::utilities::serialize::Serialize;
50use crate::utilities::serialize::SerializeStatic;
51
52const CURRENT_VERSION: u64 = 1;
53
54#[derive(Default)]
55struct DbStorageIndex {
56 version: u64,
57 graph: StorageIndex,
58 aliases: (StorageIndex, StorageIndex),
59 indexes: StorageIndex,
60 values: StorageIndex,
61}
62
63impl Serialize for DbStorageIndex {
64 fn serialize(&self) -> Vec<u8> {
65 [
66 self.version.serialize(),
67 self.graph.serialize(),
68 self.aliases.0.serialize(),
69 self.aliases.1.serialize(),
70 self.indexes.serialize(),
71 self.values.serialize(),
72 ]
73 .concat()
74 }
75
76 fn deserialize(bytes: &[u8]) -> Result<Self, DbError> {
77 let size = i64::serialized_size_static() as usize;
78
79 let version = u64::deserialize(bytes)?;
80 let graph = StorageIndex::deserialize(&bytes[size..])?;
81 let aliases_1 = StorageIndex::deserialize(&bytes[size * 2..])?;
82 let aliases_2 = StorageIndex::deserialize(&bytes[size * 3..])?;
83 let indexes = StorageIndex::deserialize(&bytes[size * 4..])?;
84 let values = StorageIndex::deserialize(&bytes[size * 5..])?;
85
86 Ok(Self {
87 version,
88 graph,
89 aliases: (aliases_1, aliases_2),
90 indexes,
91 values,
92 })
93 }
94
95 fn serialized_size(&self) -> u64 {
96 i64::serialized_size_static() * 6
97 }
98}
99
100pub struct DbImpl<Store: StorageData> {
200 storage: Storage<Store>,
201 graph: DbGraph<Store>,
202 aliases: DbIndexedMap<String, DbId, Store>,
203 indexes: DbIndexes<Store>,
204 values: DbKeyValues<Store>,
205 undo_stack: Vec<Command>,
206}
207
208pub type Db = DbImpl<FileStorageMemoryMapped>;
213
214pub type DbTransaction<'a> = Transaction<'a, FileStorageMemoryMapped>;
216
217pub type DbTransactionMut<'a> = TransactionMut<'a, FileStorageMemoryMapped>;
219
220pub type DbFile = DbImpl<FileStorage>;
224
225pub type DbFileTransaction<'a> = Transaction<'a, FileStorage>;
227
228pub type DbFileTransactionMut<'a> = TransactionMut<'a, FileStorage>;
230
231pub type DbMemory = DbImpl<MemoryStorage>;
234
235pub type DbMemoryTransaction<'a> = Transaction<'a, MemoryStorage>;
237
238pub type DbMemoryTransactionMut<'a> = TransactionMut<'a, MemoryStorage>;
240
241pub type DbAny = DbImpl<AnyStorage>;
243
244pub type DbAnyTransaction<'a> = Transaction<'a, AnyStorage>;
246
247pub type DbAnyTransactionMut<'a> = TransactionMut<'a, AnyStorage>;
249
250impl<Store: StorageData> std::fmt::Debug for DbImpl<Store> {
251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252 f.debug_struct("agdb::Db").finish_non_exhaustive()
253 }
254}
255
256impl<Store: StorageData> DbImpl<Store> {
257 pub fn new(filename: &str) -> Result<Self, DbError> {
262 match Self::try_new(filename) {
263 Ok(db) => Ok(db),
264 Err(error) => {
265 let mut db_error = DbError::from("Failed to create database");
266 db_error.cause = Some(Box::new(error));
267 Err(db_error)
268 }
269 }
270 }
271
272 pub fn with_data(data: Store) -> Result<Self, DbError> {
282 Self::try_new_with_storage(Storage::with_data(data)?)
283 }
284
285 pub fn backup(&self, filename: &str) -> Result<(), DbError> {
293 self.storage.backup(filename)
294 }
295
296 pub fn copy(&self, filename: &str) -> Result<Self, DbError> {
300 let storage = self.storage.copy(filename)?;
301 let index = storage.value::<DbStorageIndex>(StorageIndex(1))?;
302
303 let graph = DbGraph::from_storage(&storage, index.graph)?;
304 let aliases = DbIndexedMap::from_storage(&storage, index.aliases)?;
305 let indexes = DbIndexes::from_storage(&storage, index.indexes)?;
306 let values = DbKeyValues::from_storage(&storage, index.values)?;
308
309 Ok(Self {
310 storage,
311 graph,
312 aliases,
313 indexes,
314 values,
315 undo_stack: vec![],
316 })
317 }
318
319 pub fn exec<T: Query>(&self, query: T) -> Result<QueryResult, DbError> {
333 self.transaction(|transaction| transaction.exec(query))
334 }
335
336 pub fn exec_mut<T: QueryMut>(&mut self, query: T) -> Result<QueryResult, DbError> {
350 self.transaction_mut(|transaction| transaction.exec_mut(query))
351 }
352
353 pub fn filename(&self) -> &str {
356 self.storage.name()
357 }
358
359 pub fn optimize_storage(&mut self) -> Result<(), DbError> {
365 self.storage.optimize_storage()
366 }
367
368 pub fn rename(&mut self, filename: &str) -> Result<(), DbError> {
371 self.storage.rename(filename)
372 }
373
374 pub fn transaction<T, E>(
384 &self,
385 f: impl FnOnce(&Transaction<Store>) -> Result<T, E>,
386 ) -> Result<T, E> {
387 let transaction = Transaction::new(self);
388
389 f(&transaction)
390 }
391
392 pub fn transaction_mut<T, E: From<DbError>>(
409 &mut self,
410 f: impl FnOnce(&mut TransactionMut<Store>) -> Result<T, E>,
411 ) -> Result<T, E> {
412 let mut transaction = TransactionMut::new(&mut *self);
413 let result = f(&mut transaction);
414
415 if result.is_ok() {
416 transaction.commit()?;
417 } else {
418 transaction.rollback()?;
419 }
420
421 result
422 }
423
424 pub fn size(&self) -> u64 {
432 self.storage.len()
433 }
434
435 pub fn shrink_to_fit(&mut self) -> Result<(), DbError> {
441 self.graph.shrink_to_fit(&mut self.storage)?;
442 self.aliases.shrink_to_fit(&mut self.storage)?;
443 self.indexes.shrink_to_fit(&mut self.storage)?;
444 self.values.shrink_to_fit(&mut self.storage)?;
445 self.optimize_storage()
446 }
447
448 pub(crate) fn commit(&mut self) -> Result<(), DbError> {
449 self.undo_stack.clear();
450 Ok(())
451 }
452
453 pub(crate) fn rollback(&mut self) -> Result<(), DbError> {
454 let mut undo_stack = vec![];
455 std::mem::swap(&mut undo_stack, &mut self.undo_stack);
456
457 for command in undo_stack.iter().rev() {
458 match command {
459 Command::InsertAlias { id, alias } => {
460 self.aliases.insert(&mut self.storage, alias, id)?
461 }
462 Command::InsertEdge { from, to } => self
463 .graph
464 .insert_edge(&mut self.storage, *from, *to)
465 .map(|_| ())?,
466 Command::InsertIndex { key } => {
467 self.indexes.insert(&mut self.storage, key.clone())?;
468 }
469 Command::InsertToIndex { key, value, id } => self
470 .indexes
471 .index_mut(key)
472 .expect("index not found during rollback")
473 .ids_mut()
474 .insert(&mut self.storage, value, id)?,
475 Command::InsertKeyValue { id, key_value } => {
476 if let Some(index) = self.indexes.index_mut(&key_value.key) {
477 index
478 .ids_mut()
479 .insert(&mut self.storage, &key_value.value, id)?;
480 }
481 self.values
482 .insert_value(&mut self.storage, id.as_index(), key_value)?
483 }
484 Command::InsertNode => self.graph.insert_node(&mut self.storage).map(|_| ())?,
485 Command::RemoveAlias { alias } => {
486 self.aliases.remove_key(&mut self.storage, alias)?
487 }
488 Command::RemoveEdge { index } => {
489 self.graph.remove_edge(&mut self.storage, *index)?
490 }
491 Command::RemoveIndex { key } => self.indexes.remove(&mut self.storage, key)?,
492 Command::RemoveKeyValue { id, key_value } => {
493 if let Some(index) = self.indexes.index_mut(&key_value.key) {
494 index
495 .ids_mut()
496 .remove_value(&mut self.storage, &key_value.value, id)?;
497 }
498 self.values
499 .remove_value(&mut self.storage, id.as_index(), &key_value.key)?
500 }
501 Command::RemoveNode { index } => {
502 self.graph.remove_node(&mut self.storage, *index)?
503 }
504 Command::ReplaceKeyValue { id, key_value } => {
505 let old = self
506 .values
507 .insert_or_replace(&mut self.storage, id.as_index(), key_value)?
508 .expect("old value not found during rollback");
509
510 if let Some(index) = self.indexes.index_mut(&old.key) {
511 index
512 .ids_mut()
513 .remove_value(&mut self.storage, &old.value, id)?;
514 index
515 .ids_mut()
516 .insert(&mut self.storage, &key_value.value, id)?;
517 }
518
519 return Ok(());
520 }
521 }
522 }
523
524 Ok(())
525 }
526
527 pub(crate) fn alias(&self, db_id: DbId) -> Result<String, DbError> {
528 self.aliases
529 .key(&self.storage, &db_id)?
530 .ok_or(DbError::from(format!("Id '{}' not found", db_id.0)))
531 }
532
533 pub(crate) fn aliases(&self) -> Vec<(String, DbId)> {
534 self.aliases.iter(&self.storage).collect()
535 }
536
537 pub(crate) fn db_id(&self, query_id: &QueryId) -> Result<DbId, DbError> {
538 match query_id {
539 QueryId::Id(id) => Ok(DbId(self.graph_index(id.0)?.0)),
540 QueryId::Alias(alias) => Ok(self
541 .aliases
542 .value(&self.storage, alias)?
543 .ok_or(DbError::from(format!("Alias '{alias}' not found")))?),
544 }
545 }
546
547 pub(crate) fn edge_count(&self, db_id: DbId, from: bool, to: bool) -> Result<u64, DbError> {
548 let index = self.graph_index(db_id.0)?;
549
550 if let Some(node) = self.graph.node(&self.storage, index) {
551 return Ok(match (from, to) {
552 (true, true) => node.edge_count(),
553 (true, false) => node.edge_count_from(),
554 (false, true) => node.edge_count_to(),
555 (false, false) => 0,
556 });
557 }
558
559 Ok(0)
560 }
561
562 #[allow(clippy::wrong_self_convention)]
563 pub(crate) fn from_id(&self, id: DbId) -> Option<DbId> {
564 if id.0 < 0 {
565 Some(DbId(
566 self.graph.edge_from(&self.storage, GraphIndex(id.0)).0,
567 ))
568 } else {
569 None
570 }
571 }
572
573 pub(crate) fn to_id(&self, id: DbId) -> Option<DbId> {
574 if id.0 < 0 {
575 Some(DbId(self.graph.edge_to(&self.storage, GraphIndex(id.0)).0))
576 } else {
577 None
578 }
579 }
580
581 pub(crate) fn indexes(&self) -> Vec<DbKeyValue> {
582 self.indexes
583 .indexes()
584 .iter()
585 .map(|index| DbKeyValue {
586 key: index.key().clone(),
587 value: index.ids().len().into(),
588 })
589 .collect()
590 }
591
592 pub(crate) fn insert_alias(&mut self, db_id: DbId, alias: &String) -> Result<(), DbError> {
593 if let Some(old_alias) = self.aliases.key(&self.storage, &db_id)? {
594 self.undo_stack.push(Command::InsertAlias {
595 id: db_id,
596 alias: old_alias.clone(),
597 });
598 self.aliases.remove_key(&mut self.storage, &old_alias)?;
599 self.aliases.remove_key(&mut self.storage, &old_alias)?;
600 }
601
602 self.undo_stack.push(Command::RemoveAlias {
603 alias: alias.clone(),
604 });
605 self.aliases.insert(&mut self.storage, alias, &db_id)
606 }
607
608 pub(crate) fn insert_edge(&mut self, from: DbId, to: DbId) -> Result<DbId, DbError> {
609 let index =
610 self.graph
611 .insert_edge(&mut self.storage, GraphIndex(from.0), GraphIndex(to.0))?;
612 self.undo_stack.push(Command::RemoveEdge { index });
613
614 Ok(DbId(index.0))
615 }
616
617 pub(crate) fn insert_index(&mut self, key: &DbValue) -> Result<u64, DbError> {
618 if self.indexes.index(key).is_some() {
619 return Err(DbError::from(format!("Index '{key}' already exists")));
620 }
621
622 self.undo_stack
623 .push(Command::RemoveIndex { key: key.clone() });
624
625 let index = self.indexes.insert(&mut self.storage, key.clone())?;
626
627 for i in 1..self.values.len() {
628 let kvs = self.values.values(&self.storage, i)?;
629 let db_id = if self
630 .graph
631 .node(&self.storage, GraphIndex(i as i64))
632 .is_some()
633 {
634 DbId(i as i64)
635 } else {
636 DbId(-(i as i64))
637 };
638
639 for kv in kvs {
640 if kv.key == *key {
641 index
642 .ids_mut()
643 .insert(&mut self.storage, &kv.value, &db_id)?;
644 }
645 }
646 }
647
648 Ok(index.ids().len())
649 }
650
651 pub(crate) fn insert_new_alias(&mut self, db_id: DbId, alias: &String) -> Result<(), DbError> {
652 self.undo_stack.push(Command::RemoveAlias {
653 alias: alias.clone(),
654 });
655 self.aliases.insert(&mut self.storage, alias, &db_id)?;
656
657 Ok(())
658 }
659
660 pub(crate) fn insert_node(&mut self) -> Result<DbId, DbError> {
661 let index = self.graph.insert_node(&mut self.storage)?;
662 self.undo_stack.push(Command::RemoveNode { index });
663
664 Ok(DbId(index.0))
665 }
666
667 pub(crate) fn insert_key_value(
668 &mut self,
669 db_id: DbId,
670 key_value: &DbKeyValue,
671 ) -> Result<(), DbError> {
672 if let Some(index) = self.indexes.index_mut(&key_value.key) {
673 index
674 .ids_mut()
675 .insert(&mut self.storage, &key_value.value, &db_id)?;
676 }
677
678 self.undo_stack.push(Command::RemoveKeyValue {
679 id: db_id,
680 key_value: key_value.clone(),
681 });
682 self.values
683 .insert_value(&mut self.storage, db_id.as_index(), key_value)?;
684 Ok(())
685 }
686
687 pub(crate) fn insert_or_replace_key_value(
688 &mut self,
689 db_id: DbId,
690 key_value: &DbKeyValue,
691 ) -> Result<(), DbError> {
692 if let Some(old) =
693 self.values
694 .insert_or_replace(&mut self.storage, db_id.as_index(), key_value)?
695 {
696 if let Some(index) = self.indexes.index_mut(&old.key) {
697 index
698 .ids_mut()
699 .remove_value(&mut self.storage, &old.value, &db_id)?;
700 index
701 .ids_mut()
702 .insert(&mut self.storage, &key_value.value, &db_id)?;
703 }
704
705 self.undo_stack.push(Command::ReplaceKeyValue {
706 id: db_id,
707 key_value: old,
708 });
709 } else {
710 if let Some(index) = self.indexes.index_mut(&key_value.key) {
711 index
712 .ids_mut()
713 .insert(&mut self.storage, &key_value.value, &db_id)?;
714 }
715
716 self.undo_stack.push(Command::RemoveKeyValue {
717 id: db_id,
718 key_value: key_value.clone(),
719 });
720 }
721
722 Ok(())
723 }
724
725 pub(crate) fn keys(&self, db_id: DbId) -> Result<Vec<DbValue>, DbError> {
726 self.values.keys(&self.storage, db_id.as_index())
727 }
728
729 pub(crate) fn key_count(&self, db_id: DbId) -> Result<u64, DbError> {
730 self.values.key_count(&self.storage, db_id.as_index())
731 }
732
733 pub(crate) fn node_count(&self) -> Result<u64, DbError> {
734 self.graph.node_count(&self.storage)
735 }
736
737 pub(crate) fn remove(&mut self, query_id: &QueryId) -> Result<bool, DbError> {
738 match query_id {
739 QueryId::Id(db_id) => self.remove_id(*db_id),
740 QueryId::Alias(alias) => {
741 if let Some(db_id) = self.aliases.value(&self.storage, alias)? {
742 self.remove_node(db_id, GraphIndex(db_id.0), Some(alias.clone()))?;
743 self.remove_all_values(db_id)?;
744 Ok(true)
745 } else {
746 Ok(false)
747 }
748 }
749 }
750 }
751
752 pub(crate) fn remove_id(&mut self, db_id: DbId) -> Result<bool, DbError> {
753 if let Ok(graph_index) = self.graph_index(db_id.0) {
754 if graph_index.is_node() {
755 self.remove_node(db_id, graph_index, self.aliases.key(&self.storage, &db_id)?)?;
756 } else {
757 self.remove_edge(graph_index)?;
758 }
759 self.remove_all_values(db_id)?;
760 return Ok(true);
761 }
762
763 Ok(false)
764 }
765
766 pub(crate) fn remove_alias(&mut self, alias: &String) -> Result<bool, DbError> {
767 if let Some(id) = self.aliases.value(&self.storage, alias)? {
768 self.undo_stack.push(Command::InsertAlias {
769 id,
770 alias: alias.clone(),
771 });
772 self.aliases.remove_key(&mut self.storage, alias)?;
773 self.aliases.remove_key(&mut self.storage, alias)?;
774
775 return Ok(true);
776 }
777
778 Ok(false)
779 }
780
781 pub(crate) fn remove_index(&mut self, key: &DbValue) -> Result<u64, DbError> {
782 let mut count = None;
783
784 if let Some(index) = self.indexes.index(key) {
785 for (value, id) in index.ids().iter(&self.storage) {
786 self.undo_stack.push(Command::InsertToIndex {
787 key: key.clone(),
788 value: value.clone(),
789 id,
790 });
791 }
792
793 count = Some(index.ids().len());
794 }
795
796 if let Some(count) = count {
797 self.undo_stack
798 .push(Command::InsertIndex { key: key.clone() });
799 self.indexes.remove(&mut self.storage, key)?;
800 Ok(count)
801 } else {
802 Ok(0)
803 }
804 }
805
806 pub(crate) fn reserve_key_value_capacity(
807 &mut self,
808 db_id: DbId,
809 additional: u64,
810 ) -> Result<(), DbError> {
811 self.values
812 .reserve_capacity(&mut self.storage, db_id.as_index(), additional)
813 }
814
815 pub(crate) fn search_index(
816 &self,
817 key: &DbValue,
818 value: &DbValue,
819 ) -> Result<Vec<DbId>, DbError> {
820 if let Some(index) = self.indexes.index(key) {
821 Ok(index.ids().values(&self.storage, value)?)
822 } else {
823 Err(DbError::from(format!("Index '{key}' not found")))
824 }
825 }
826
827 pub(crate) fn search_from(
828 &self,
829 from: DbId,
830 algorithm: SearchQueryAlgorithm,
831 limit: u64,
832 offset: u64,
833 conditions: &Vec<QueryCondition>,
834 ) -> Result<Vec<DbId>, DbError> {
835 let search = GraphSearch::from((&self.graph, &self.storage));
836
837 let indexes = match (limit, offset) {
838 (0, 0) => match algorithm {
839 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search(
840 GraphIndex(from.0),
841 DefaultHandler::new(self, conditions),
842 )?,
843 SearchQueryAlgorithm::DepthFirst => search.depth_first_search(
844 GraphIndex(from.0),
845 DefaultHandler::new(self, conditions),
846 )?,
847 _ => search.elements(DefaultHandler::new(self, conditions))?,
848 },
849
850 (_, 0) => match algorithm {
851 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search(
852 GraphIndex(from.0),
853 LimitHandler::new(limit, self, conditions),
854 )?,
855 SearchQueryAlgorithm::DepthFirst => search.depth_first_search(
856 GraphIndex(from.0),
857 LimitHandler::new(limit, self, conditions),
858 )?,
859 _ => search.elements(LimitHandler::new(limit, self, conditions))?,
860 },
861
862 (0, _) => match algorithm {
863 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search(
864 GraphIndex(from.0),
865 OffsetHandler::new(offset, self, conditions),
866 )?,
867 SearchQueryAlgorithm::DepthFirst => search.depth_first_search(
868 GraphIndex(from.0),
869 OffsetHandler::new(offset, self, conditions),
870 )?,
871 _ => search.elements(OffsetHandler::new(offset, self, conditions))?,
872 },
873
874 (_, _) => match algorithm {
875 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search(
876 GraphIndex(from.0),
877 LimitOffsetHandler::new(limit, offset, self, conditions),
878 )?,
879 SearchQueryAlgorithm::DepthFirst => search.depth_first_search(
880 GraphIndex(from.0),
881 LimitOffsetHandler::new(limit, offset, self, conditions),
882 )?,
883 _ => search.elements(LimitOffsetHandler::new(limit, offset, self, conditions))?,
884 },
885 };
886
887 Ok(indexes.iter().map(|index| DbId(index.0)).collect())
888 }
889
890 pub(crate) fn search_to(
891 &self,
892 to: DbId,
893 algorithm: SearchQueryAlgorithm,
894 limit: u64,
895 offset: u64,
896 conditions: &Vec<QueryCondition>,
897 ) -> Result<Vec<DbId>, DbError> {
898 let search = GraphSearch::from((&self.graph, &self.storage));
899
900 let indexes = match (limit, offset) {
901 (0, 0) => match algorithm {
902 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search_reverse(
903 GraphIndex(to.0),
904 DefaultHandler::new(self, conditions),
905 )?,
906 _ => search.depth_first_search_reverse(
907 GraphIndex(to.0),
908 DefaultHandler::new(self, conditions),
909 )?,
910 },
911
912 (_, 0) => match algorithm {
913 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search_reverse(
914 GraphIndex(to.0),
915 LimitHandler::new(limit, self, conditions),
916 )?,
917 _ => search.depth_first_search_reverse(
918 GraphIndex(to.0),
919 LimitHandler::new(limit, self, conditions),
920 )?,
921 },
922
923 (0, _) => match algorithm {
924 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search_reverse(
925 GraphIndex(to.0),
926 OffsetHandler::new(offset, self, conditions),
927 )?,
928 _ => search.depth_first_search_reverse(
929 GraphIndex(to.0),
930 OffsetHandler::new(offset, self, conditions),
931 )?,
932 },
933
934 (_, _) => match algorithm {
935 SearchQueryAlgorithm::BreadthFirst => search.breadth_first_search_reverse(
936 GraphIndex(to.0),
937 LimitOffsetHandler::new(limit, offset, self, conditions),
938 )?,
939 _ => search.depth_first_search_reverse(
940 GraphIndex(to.0),
941 LimitOffsetHandler::new(limit, offset, self, conditions),
942 )?,
943 },
944 };
945
946 Ok(indexes.iter().map(|index| DbId(index.0)).collect())
947 }
948
949 pub(crate) fn search_from_to(
950 &self,
951 from: DbId,
952 to: DbId,
953 conditions: &Vec<QueryCondition>,
954 ) -> Result<Vec<DbId>, DbError> {
955 Ok(GraphSearch::from((&self.graph, &self.storage))
956 .path(
957 GraphIndex(from.0),
958 GraphIndex(to.0),
959 PathHandler::new(self, conditions),
960 )?
961 .iter()
962 .map(|index| DbId(index.0))
963 .collect())
964 }
965
966 pub(crate) fn values(&self, db_id: DbId) -> Result<Vec<DbKeyValue>, DbError> {
967 self.values.values(&self.storage, db_id.as_index())
968 }
969
970 pub(crate) fn values_by_keys(
971 &self,
972 db_id: DbId,
973 keys: &[DbValue],
974 ) -> Result<Vec<DbKeyValue>, DbError> {
975 self.values
976 .values_by_keys(&self.storage, db_id.as_index(), keys)
977 }
978
979 fn graph_index(&self, id: i64) -> Result<GraphIndex, DbError> {
980 match id.cmp(&0) {
981 std::cmp::Ordering::Less => {
982 if self.graph.edge(&self.storage, GraphIndex(id)).is_some() {
983 return Ok(GraphIndex(id));
984 }
985 }
986 std::cmp::Ordering::Equal => {}
987 std::cmp::Ordering::Greater => {
988 if self.graph.node(&self.storage, GraphIndex(id)).is_some() {
989 return Ok(GraphIndex(id));
990 }
991 }
992 }
993
994 Err(DbError::from(format!("Id '{id}' not found")))
995 }
996
997 fn node_edges(
998 &self,
999 graph_index: GraphIndex,
1000 ) -> Result<Vec<(GraphIndex, GraphIndex, GraphIndex)>, DbError> {
1001 let mut edges = vec![];
1002 let node = self
1003 .graph
1004 .node(&self.storage, graph_index)
1005 .ok_or(DbError::from("Data integrity corrupted"))?;
1006
1007 for edge in node.edge_iter_from() {
1008 edges.push((edge.index(), edge.index_from(), edge.index_to()));
1009 }
1010
1011 for edge in node.edge_iter_to() {
1012 let from = edge.index_from();
1013 if from != graph_index {
1014 edges.push((edge.index(), from, edge.index_to()));
1015 }
1016 }
1017
1018 Ok(edges)
1019 }
1020
1021 fn remove_edge(&mut self, graph_index: GraphIndex) -> Result<(), DbError> {
1022 let (from, to) = {
1023 let edge = self
1024 .graph
1025 .edge(&self.storage, graph_index)
1026 .ok_or(DbError::from("Graph integrity corrupted"))?;
1027 (edge.index_from(), edge.index_to())
1028 };
1029
1030 self.graph.remove_edge(&mut self.storage, graph_index)?;
1031 self.undo_stack.push(Command::InsertEdge { from, to });
1032 Ok(())
1033 }
1034
1035 fn remove_node(
1036 &mut self,
1037 db_id: DbId,
1038 graph_index: GraphIndex,
1039 alias: Option<String>,
1040 ) -> Result<(), DbError> {
1041 if let Some(alias) = alias {
1042 self.undo_stack.push(Command::InsertAlias {
1043 alias: alias.clone(),
1044 id: db_id,
1045 });
1046 self.aliases.remove_key(&mut self.storage, &alias)?;
1047 self.aliases.remove_key(&mut self.storage, &alias)?;
1048 }
1049
1050 for edge in self.node_edges(graph_index)? {
1051 self.graph.remove_edge(&mut self.storage, edge.0)?;
1052 self.undo_stack.push(Command::InsertEdge {
1053 from: edge.1,
1054 to: edge.2,
1055 });
1056 self.remove_all_values(DbId(edge.0.0))?;
1057 }
1058
1059 self.graph.remove_node(&mut self.storage, graph_index)?;
1060 self.undo_stack.push(Command::InsertNode);
1061 Ok(())
1062 }
1063
1064 pub(crate) fn remove_keys(&mut self, db_id: DbId, keys: &[DbValue]) -> Result<i64, DbError> {
1065 let mut result = 0;
1066
1067 for key_value in self.values.values(&self.storage, db_id.as_index())? {
1068 if keys.contains(&key_value.key) {
1069 if let Some(index) = self.indexes.index_mut(&key_value.key) {
1070 index
1071 .ids_mut()
1072 .remove_value(&mut self.storage, &key_value.value, &db_id)?;
1073 }
1074 self.values
1075 .remove_value(&mut self.storage, db_id.as_index(), &key_value.key)?;
1076 self.undo_stack.push(Command::InsertKeyValue {
1077 id: db_id,
1078 key_value,
1079 });
1080 result -= 1;
1081 }
1082 }
1083
1084 Ok(result)
1085 }
1086
1087 fn remove_all_values(&mut self, db_id: DbId) -> Result<(), DbError> {
1088 for key_value in self.values.values(&self.storage, db_id.as_index())? {
1089 if let Some(index) = self.indexes.index_mut(&key_value.key) {
1090 index
1091 .ids_mut()
1092 .remove_value(&mut self.storage, &key_value.value, &db_id)?;
1093 }
1094
1095 self.undo_stack.push(Command::InsertKeyValue {
1096 id: db_id,
1097 key_value,
1098 });
1099 }
1100
1101 self.values.remove(&mut self.storage, db_id.as_index())?;
1102
1103 Ok(())
1104 }
1105
1106 fn try_new_with_storage(mut storage: Storage<Store>) -> Result<Self, DbError> {
1107 let graph_storage;
1108 let aliases_storage;
1109 let indexes_storage;
1110 let values_storage;
1111
1112 if storage.value_size(StorageIndex(1)).is_err() {
1113 storage.insert(&DbStorageIndex::default())?;
1114 graph_storage = DbGraph::new(&mut storage)?;
1115 aliases_storage = DbIndexedMap::new(&mut storage)?;
1116 indexes_storage = DbIndexes::new(&mut storage)?;
1117 values_storage = DbKeyValues::new(&mut storage)?;
1118 let db_storage_index = DbStorageIndex {
1119 version: CURRENT_VERSION,
1120 graph: graph_storage.storage_index(),
1121 aliases: aliases_storage.storage_index(),
1122 indexes: indexes_storage.storage_index(),
1123 values: values_storage.storage_index(),
1124 };
1125 storage.insert_at(StorageIndex(1), 0, &db_storage_index)?;
1126 } else {
1127 let index = if let Ok(index) = storage.value::<DbStorageIndex>(StorageIndex(1)) {
1128 index
1129 } else {
1130 legacy::convert_to_current_version(&mut storage)?;
1131 storage.value::<DbStorageIndex>(StorageIndex(1))?
1132 };
1133
1134 graph_storage = DbGraph::from_storage(&storage, index.graph)?;
1135 aliases_storage = DbIndexedMap::from_storage(&storage, index.aliases)?;
1136 indexes_storage = DbIndexes::from_storage(&storage, index.indexes)?;
1137 values_storage = DbKeyValues::from_storage(&storage, index.values)?;
1138 }
1139
1140 Ok(Self {
1141 storage,
1142 graph: graph_storage,
1143 aliases: aliases_storage,
1144 indexes: indexes_storage,
1145 values: values_storage,
1146 undo_stack: vec![],
1147 })
1148 }
1149
1150 fn try_new(filename: &str) -> Result<Self, DbError> {
1151 Self::try_new_with_storage(Storage::new(filename)?)
1152 }
1153
1154 pub(crate) fn evaluate_condition(
1155 &self,
1156 index: GraphIndex,
1157 distance: u64,
1158 condition: &QueryConditionData,
1159 ) -> Result<SearchControl, DbError> {
1160 match condition {
1161 QueryConditionData::Distance(value) => Ok(value.compare_distance(distance)),
1162 QueryConditionData::Edge => Ok(SearchControl::Continue(index.is_edge())),
1163 QueryConditionData::EdgeCount(value) => Ok(SearchControl::Continue(
1164 if let Some(node) = self.graph.node(&self.storage, index) {
1165 value.compare(node.edge_count())
1166 } else {
1167 false
1168 },
1169 )),
1170 QueryConditionData::EdgeCountFrom(value) => Ok(SearchControl::Continue(
1171 if let Some(node) = self.graph.node(&self.storage, index) {
1172 value.compare(node.edge_count_from())
1173 } else {
1174 false
1175 },
1176 )),
1177 QueryConditionData::EdgeCountTo(value) => Ok(SearchControl::Continue(
1178 if let Some(node) = self.graph.node(&self.storage, index) {
1179 value.compare(node.edge_count_to())
1180 } else {
1181 false
1182 },
1183 )),
1184 QueryConditionData::Ids(values) => {
1185 Ok(SearchControl::Continue(values.iter().any(|id| {
1186 index.0
1187 == match id {
1188 QueryId::Id(id) => id.0,
1189 QueryId::Alias(alias) => {
1190 self.aliases
1191 .value(&self.storage, alias)
1192 .unwrap_or_default()
1193 .unwrap_or_default()
1194 .0
1195 }
1196 }
1197 })))
1198 }
1199 QueryConditionData::KeyValue(kvc) => Ok(SearchControl::Continue(
1200 if let Some(value) = self.values.value(&self.storage, index.as_u64(), &kvc.key)? {
1201 kvc.value.compare(&value)
1202 } else {
1203 false
1204 },
1205 )),
1206 QueryConditionData::Keys(values) => {
1207 let keys = self.values.keys(&self.storage, index.as_u64())?;
1208 Ok(SearchControl::Continue(
1209 values.iter().all(|k| keys.contains(k)),
1210 ))
1211 }
1212 QueryConditionData::Node => Ok(SearchControl::Continue(index.is_node())),
1213 QueryConditionData::Where(conditions) => {
1214 self.evaluate_conditions(index, distance, conditions)
1215 }
1216 }
1217 }
1218
1219 pub(crate) fn evaluate_conditions(
1220 &self,
1221 index: GraphIndex,
1222 distance: u64,
1223 conditions: &[QueryCondition],
1224 ) -> Result<SearchControl, DbError> {
1225 let mut result = SearchControl::Continue(true);
1226
1227 for condition in conditions {
1228 let mut control = self.evaluate_condition(index, distance, &condition.data)?;
1229
1230 match condition.modifier {
1231 QueryConditionModifier::Beyond => {
1232 if control.is_true() {
1233 control = control.and(SearchControl::Continue(true));
1234 } else {
1235 control = SearchControl::Stop(true);
1236 }
1237 }
1238 QueryConditionModifier::Not => control.flip(),
1239 QueryConditionModifier::NotBeyond => {
1240 if control.is_true() {
1241 control = control.and(SearchControl::Stop(true));
1242 } else {
1243 control = SearchControl::Continue(true);
1244 }
1245 }
1246 _ => {}
1247 };
1248
1249 result = match condition.logic {
1250 QueryConditionLogic::And => result.and(control),
1251 QueryConditionLogic::Or => result.or(control),
1252 };
1253 }
1254
1255 Ok(result)
1256 }
1257}
1258
1259impl<Store: StorageData> Drop for DbImpl<Store> {
1260 fn drop(&mut self) {
1261 let _ = self.storage.optimize_storage();
1262 }
1263}
1264
1265impl DbAny {
1266 pub fn new_file(filename: &str) -> Result<Self, DbError> {
1268 Self::try_new_any(filename, Self::try_new_file)
1269 }
1270
1271 pub fn new_mapped(filename: &str) -> Result<Self, DbError> {
1273 Self::try_new_any(filename, Self::try_new_mapped)
1274 }
1275
1276 pub fn new_memory(filename: &str) -> Result<Self, DbError> {
1278 Self::try_new_any(filename, Self::try_new_memory)
1279 }
1280
1281 fn try_new_any(
1282 filename: &str,
1283 init: fn(&str) -> Result<DbImpl<AnyStorage>, DbError>,
1284 ) -> Result<Self, DbError> {
1285 match init(filename) {
1286 Ok(db) => Ok(db),
1287 Err(error) => {
1288 let mut db_error = DbError::from("Failed to create database");
1289 db_error.cause = Some(Box::new(error));
1290 Err(db_error)
1291 }
1292 }
1293 }
1294
1295 fn try_new_memory(filename: &str) -> Result<DbImpl<AnyStorage>, DbError> {
1296 Self::try_new_with_storage(Storage::with_data(AnyStorage::Memory(MemoryStorage::new(
1297 filename,
1298 )?))?)
1299 }
1300
1301 fn try_new_file(filename: &str) -> Result<DbImpl<AnyStorage>, DbError> {
1302 Self::try_new_with_storage(Storage::with_data(AnyStorage::File(FileStorage::new(
1303 filename,
1304 )?))?)
1305 }
1306
1307 fn try_new_mapped(filename: &str) -> Result<DbImpl<AnyStorage>, DbError> {
1308 Self::try_new_with_storage(Storage::with_data(AnyStorage::MemoryMapped(
1309 FileStorageMemoryMapped::new(filename)?,
1310 ))?)
1311 }
1312}
1313
1314mod legacy {
1316 use crate::DbError;
1317 use crate::DbId;
1318 use crate::DbKeyValue;
1319 use crate::StorageData;
1320 use crate::collections::map::MapIterator;
1321 use crate::collections::multi_map::MultiMapStorage;
1322 use crate::db::CURRENT_VERSION;
1323 use crate::db::DbStorageIndex;
1324 use crate::db::db_key_value::DbKeyValues;
1325 use crate::storage::Storage;
1326 use crate::storage::StorageIndex;
1327 use crate::utilities::serialize::Serialize;
1328 use crate::utilities::serialize::SerializeStatic;
1329 use std::marker::PhantomData;
1330
1331 pub(crate) struct DbStorageIndexLegacy {
1332 pub(crate) graph: StorageIndex,
1333 pub(crate) aliases: (StorageIndex, StorageIndex),
1334 pub(crate) indexes: StorageIndex,
1335 pub(crate) values: StorageIndex,
1336 }
1337
1338 impl Serialize for DbStorageIndexLegacy {
1339 fn serialize(&self) -> Vec<u8> {
1340 [
1341 self.graph.serialize(),
1342 self.aliases.0.serialize(),
1343 self.aliases.1.serialize(),
1344 self.indexes.serialize(),
1345 self.values.serialize(),
1346 ]
1347 .concat()
1348 }
1349
1350 fn deserialize(bytes: &[u8]) -> Result<Self, DbError> {
1351 let size = i64::serialized_size_static() as usize;
1352
1353 let graph = StorageIndex::deserialize(bytes)?;
1354 let aliases_1 = StorageIndex::deserialize(&bytes[size..])?;
1355 let aliases_2 = StorageIndex::deserialize(&bytes[size * 2..])?;
1356 let indexes = StorageIndex::deserialize(&bytes[size * 3..])?;
1357 let values = StorageIndex::deserialize(&bytes[size * 4..])?;
1358
1359 Ok(Self {
1360 graph,
1361 aliases: (aliases_1, aliases_2),
1362 indexes,
1363 values,
1364 })
1365 }
1366
1367 fn serialized_size(&self) -> u64 {
1368 i64::serialized_size_static() * 5
1369 }
1370 }
1371
1372 pub fn convert_to_current_version<D: StorageData>(
1373 storage: &mut Storage<D>,
1374 ) -> Result<DbStorageIndex, DbError> {
1375 let legacy_index = storage.value::<DbStorageIndexLegacy>(StorageIndex(1))?;
1376 let legacy_values =
1377 MultiMapStorage::<DbId, DbKeyValue, _>::from_storage(storage, legacy_index.values)?;
1378 let t = storage.transaction();
1379 let mut values = DbKeyValues::new(storage)?;
1380 let mut pos = 0;
1381
1382 loop {
1383 let mut it = MapIterator {
1384 pos,
1385 data: &legacy_values.data,
1386 storage,
1387 phantom_data: PhantomData,
1388 };
1389
1390 if let Some((db_id, kv)) = it.next() {
1391 pos = it.pos;
1392 values.insert_value(storage, db_id.as_index(), &kv)?;
1393 } else {
1394 break;
1395 }
1396 }
1397
1398 legacy_values.remove_from_storage(storage)?;
1399
1400 let db_storage_index = DbStorageIndex {
1401 version: CURRENT_VERSION,
1402 graph: legacy_index.graph,
1403 aliases: legacy_index.aliases,
1404 indexes: legacy_index.indexes,
1405 values: values.storage_index(),
1406 };
1407
1408 storage.replace(StorageIndex(1), &db_storage_index)?;
1409 storage.commit(t)?;
1410 storage.optimize_storage()?;
1411 Ok(db_storage_index)
1412 }
1413}
1414
1415#[cfg(test)]
1416mod tests {
1417 use super::*;
1418 use crate::test_utilities::test_file::TestFile;
1419
1420 #[test]
1421 fn db_storage_index_serialized_size() {
1422 assert_eq!(DbStorageIndex::default().serialized_size(), 48);
1423 }
1424
1425 #[test]
1426 fn derived_from_debug() {
1427 let test_file = TestFile::new();
1428 let db = Db::new(test_file.file_name()).unwrap();
1429 let _ = format!("{db:?}");
1430 }
1431
1432 #[test]
1433 fn db_storage_index_legacy_serialization() {
1434 let index = legacy::DbStorageIndexLegacy {
1435 graph: StorageIndex(1),
1436 aliases: (StorageIndex(2), StorageIndex(3)),
1437 indexes: StorageIndex(4),
1438 values: StorageIndex(5),
1439 };
1440 let serialized = index.serialize();
1441 let deserialized = legacy::DbStorageIndexLegacy::deserialize(&serialized).unwrap();
1442 assert_eq!(index.graph, deserialized.graph);
1443 assert_eq!(index.aliases.0, deserialized.aliases.0);
1444 assert_eq!(index.aliases.1, deserialized.aliases.1);
1445 assert_eq!(index.indexes, deserialized.indexes);
1446 assert_eq!(index.values, deserialized.values);
1447 assert_eq!(index.serialized_size(), deserialized.serialized_size());
1448 }
1449}