realm_db_reader/column/
mod.rs1use std::fmt::Debug;
2
3use crate::array::RealmRef;
4pub(crate) use crate::column::backlink::create_backlink_column;
5pub(crate) use crate::column::bool::create_bool_column;
6pub(crate) use crate::column::bool_optional::create_bool_null_column;
7use crate::column::bptree::BpTree;
8pub(crate) use crate::column::double::create_double_column;
9pub(crate) use crate::column::float::create_float_column;
10pub(crate) use crate::column::integer::create_int_column;
11pub(crate) use crate::column::integer_optional::create_int_null_column;
12pub(crate) use crate::column::link::create_link_column;
13pub(crate) use crate::column::linklist::create_linklist_column;
14pub(crate) use crate::column::string::create_string_column;
15pub(crate) use crate::column::subtable::create_subtable_column;
16pub(crate) use crate::column::timestamp::create_timestamp_column;
17use crate::index::Index;
18use crate::realm::Realm;
19use crate::table::ColumnAttributes;
20use crate::traits::{ArrayLike, Node, NodeWithContext};
21use crate::value::Value;
22use std::sync::Arc;
23
24mod backlink;
25mod bool;
26mod bool_optional;
27mod bptree;
28mod double;
29mod float;
30mod integer;
31mod integer_optional;
32mod link;
33mod linklist;
34mod string;
35mod subtable;
36mod timestamp;
37
38pub trait Column: Debug + Send {
40 fn get(&self, index: usize) -> crate::RealmResult<Value>;
42
43 fn is_null(&self, index: usize) -> crate::RealmResult<bool>;
46
47 fn count(&self) -> crate::RealmResult<usize>;
49
50 fn nullable(&self) -> bool;
53
54 fn is_indexed(&self) -> bool;
58
59 fn get_row_number_by_index(&self, lookup_value: &Value) -> crate::RealmResult<Option<usize>>;
63
64 fn name(&self) -> Option<&str>;
66}
67
68pub(crate) trait ColumnType {
70 type Value: Into<Value>;
71 type LeafContext: Copy + Debug;
72 type LeafType: ArrayLike<Self::Value, Self::LeafContext>;
73}
74
75struct ColumnImpl<T: ColumnType> {
76 tree: BpTree<T>,
77 index: Option<Index>,
78 attributes: ColumnAttributes,
79 name: Option<String>,
80}
81
82impl<T: ColumnType> Debug for ColumnImpl<T> {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 f.debug_struct("ColumnImpl")
85 .field("tree", &self.tree)
86 .field("attributes", &self.attributes)
87 .field("name", &self.name)
88 .finish()
89 }
90}
91
92impl<T: ColumnType + Send> Column for ColumnImpl<T>
93where
94 Value: From<T::Value>,
95 <T as ColumnType>::LeafContext: Send,
96 <T as ColumnType>::LeafType: Send,
97{
98 fn get(&self, index: usize) -> crate::RealmResult<Value> {
99 Ok(Value::from(self.tree.get(index)?))
100 }
101
102 fn is_null(&self, index: usize) -> crate::RealmResult<bool> {
103 self.tree.is_null(index)
104 }
105
106 fn count(&self) -> crate::RealmResult<usize> {
107 self.tree.count()
108 }
109
110 fn nullable(&self) -> bool {
111 self.attributes.is_nullable()
112 }
113
114 fn is_indexed(&self) -> bool {
115 self.attributes.is_indexed()
116 }
117
118 fn get_row_number_by_index(&self, lookup_value: &Value) -> crate::RealmResult<Option<usize>> {
119 let Some(index) = &self.index else {
120 panic!("Column {:?} is not indexed", self.name());
121 };
122
123 index.find_first(lookup_value)
124 }
125
126 fn name(&self) -> Option<&str> {
127 self.name.as_deref()
128 }
129}
130
131impl<T: ColumnType> ColumnImpl<T> {
132 pub(crate) fn new(
133 realm: Arc<Realm>,
134 data_ref: RealmRef,
135 index_ref: Option<RealmRef>,
136 attributes: ColumnAttributes,
137 name: Option<String>,
138 context: T::LeafContext,
139 ) -> crate::RealmResult<Self> {
140 let tree = BpTree::from_ref_with_context(Arc::clone(&realm), data_ref, context)?;
141 let index = index_ref
142 .map(|ref_| Index::from_ref(realm, ref_))
143 .transpose()?;
144
145 Ok(Self {
146 tree,
147 index,
148 attributes,
149 name,
150 })
151 }
152}