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