assembly_fdb/core/
mod.rs

1//! # The data structures for representing the file/database.
2//!
3//! An FDB file is layed out as a hash map. The top level is a list
4//! of tables, lexically ordered by their name (all uppercase names
5//! before all lowercase ones).
6//!
7//! Each table consists of an array of Buckets, where each bucket
8//! Corresponds to one hash value of the primary column.
9//!
10//! Each bucket consists of a list of rows. These rows may be sorted
11//! in ascending order of primary keys, but that is not fully verified.
12//!
13//! Each row contains a vector of fields, with a data type and respective
14//! data.
15//!
16//! Each Table has a list of columns with the names and default data
17//! Types corresponding to the layout of each row.
18
19pub mod iter;
20#[cfg(feature = "core-loader")]
21pub mod loader;
22
23pub use assembly_fdb_core::value::{
24    mem::MemContext,
25    owned::{Field, OwnedContext},
26    Context, Value, ValueMapperMut, ValueType,
27};
28use std::collections::BTreeMap;
29
30/// A sequence of fields
31#[derive(Debug, Default)]
32pub struct Row(Vec<Field>);
33
34impl From<Vec<Field>> for Row {
35    fn from(fields: Vec<Field>) -> Self {
36        Row(fields)
37    }
38}
39
40impl Row {
41    /// Create a new, empty row
42    pub fn new() -> Row {
43        Row(Vec::new())
44    }
45
46    /// Return the fields of this row
47    pub fn into_fields(self) -> Vec<Field> {
48        self.0
49    }
50
51    /// Get a reference to the fields vector
52    pub fn fields(&self) -> &Vec<Field> {
53        &self.0
54    }
55
56    /// Get a mutable reference to the fields vector
57    pub fn fields_mut(&mut self) -> &mut Vec<Field> {
58        &mut self.0
59    }
60}
61
62/// A container of rows with the same hash value
63#[derive(Debug, Default)]
64pub struct Bucket(pub Vec<Row>);
65
66impl Bucket {
67    /// Create a new empty bucket
68    pub fn new() -> Bucket {
69        Bucket(Vec::new())
70    }
71
72    /// Get the rows of the bucket
73    pub fn rows(self) -> Vec<Row> {
74        self.0
75    }
76
77    /// Get a reference to the rows from a reference to a bucket
78    pub fn rows_ref(&self) -> &Vec<Row> {
79        &self.0
80    }
81
82    /// Get a mutable reference to the rows from a reference to a bucket
83    pub fn rows_mut(&mut self) -> &mut Vec<Row> {
84        &mut self.0
85    }
86}
87
88/// Name and default type for one field in each row
89#[derive(Debug)]
90pub struct Column {
91    /// The name of the column
92    pub name: String,
93    /// The type of the column
94    pub field_type: ValueType,
95}
96
97impl From<(&str, ValueType)> for Column {
98    fn from(data: (&str, ValueType)) -> Self {
99        Column {
100            name: String::from(data.0),
101            field_type: data.1,
102        }
103    }
104}
105
106/// A list of columns with types and a name
107#[derive(Debug)]
108pub struct TableDef {
109    /// The columns of the table in the same order as in the rows
110    pub columns: Vec<Column>,
111    /// The name of the table
112    pub name: String,
113}
114
115/// An array of buckets, and a collection of rows
116#[derive(Debug, Default)]
117pub struct TableData {
118    /// The buckets in this table
119    pub buckets: Vec<Bucket>,
120}
121
122impl TableData {
123    /// Creates a new instance
124    pub fn new() -> Self {
125        TableData {
126            buckets: Vec::new(),
127        }
128    }
129}
130
131/// A list of buckets and thus collection of rows with a name
132#[derive(Debug)]
133pub struct Table {
134    definition: TableDef,
135    data: TableData,
136}
137
138impl Table {
139    /// Creates a new table from a definition and data struct
140    pub fn from(definition: TableDef, data: TableData) -> Self {
141        Table { definition, data }
142    }
143
144    /// Creates a new table without data
145    pub fn new(definition: TableDef) -> Self {
146        let data = TableData::new();
147        Table { definition, data }
148    }
149
150    /// Extract the buckets vector
151    pub fn into_buckets(self) -> Vec<Bucket> {
152        self.data.buckets
153    }
154
155    /// Returns a reference to the slice of buckets
156    pub fn buckets(&self) -> &[Bucket] {
157        &self.data.buckets
158    }
159
160    /// Returns a mutable reference to the vector of buckets
161    pub fn buckets_mut(&mut self) -> &mut Vec<Bucket> {
162        &mut self.data.buckets
163    }
164
165    /// Extract the columns vector
166    pub fn into_columns(self) -> Vec<Column> {
167        self.definition.columns
168    }
169
170    /// Returns a reference to the slice of columns
171    pub fn columns(&self) -> &[Column] {
172        &self.definition.columns
173    }
174
175    /// Returns a mutable reference to the vector of columns
176    pub fn columns_mut(&mut self) -> &mut Vec<Column> {
177        &mut self.definition.columns
178    }
179
180    /// Returns the name of the table
181    pub fn name(&self) -> &str {
182        self.definition.name.as_ref()
183    }
184}
185
186/// # An ordered map of tables
187///
188/// A schema is an ordered map of tables. It represents a full
189/// relational database and is the root struct type in this module.
190#[derive(Debug, Default)]
191pub struct Schema {
192    /// The tables in this schema
193    pub tables: BTreeMap<String, Table>,
194}
195
196impl Schema {
197    /// Create a new empty schema
198    pub fn new() -> Schema {
199        Schema {
200            tables: BTreeMap::new(),
201        }
202    }
203
204    /// Get a reference to the table of that name it it exists
205    pub fn table(&self, name: &str) -> Option<&Table> {
206        self.tables.get(name)
207    }
208
209    /// Get a mutable reference to the table of that name it it exists
210    pub fn table_mut(&mut self, name: &str) -> Option<&mut Table> {
211        self.tables.get_mut(name)
212    }
213
214    /// Returns the number of tables
215    pub fn table_count(&self) -> usize {
216        self.tables.len()
217    }
218}
219
220impl From<Vec<Table>> for Schema {
221    fn from(tables: Vec<Table>) -> Self {
222        let mut tree = BTreeMap::new();
223        for table in tables {
224            tree.insert(table.name().to_string(), table);
225        }
226        Schema { tables: tree }
227    }
228}