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
use std::iter::Iterator;
use std::collections::HashSet;
use super::error::DBError;
use super::types::Type;
#[derive(Clone)]
pub struct Attribute {
pub name: String,
pub nullable: bool,
pub dtype: Type,
}
#[derive(Clone, Default)]
pub struct Schema {
attrs: Vec<Attribute>,
}
pub struct AttributeIter<'a> {
schema: &'a Schema,
cur: usize
}
impl Attribute {
pub fn rename<S: Into<String>>(&self, name: S) -> Attribute {
Attribute { name: name.into(), nullable: self.nullable, dtype: self.dtype }
}
}
impl Schema {
pub fn from_slice(attrs: &[Attribute]) -> Result<Schema, DBError> {
let mut names = HashSet::with_capacity(attrs.len());
for a in attrs {
if names.replace(a.name.clone()).is_some() {
return Err(DBError::AttributeDuplicate(a.name.clone()))
}
}
Ok(Schema { attrs: Vec::from(attrs) })
}
pub fn from_vec(attrs: Vec<Attribute>) -> Result<Schema, DBError> {
Self::from_slice(attrs.as_slice())
}
pub fn from_attr(attr: Attribute) -> Schema {
Schema { attrs: vec!(attr) }
}
pub fn make_one_attr<S: Into<String>>(name: S, nullable: bool, dtype: Type) -> Schema {
Schema::from_attr(Attribute{name: name.into(), nullable: nullable, dtype: dtype})
}
pub fn count(&self) -> usize {
self.attrs.len()
}
pub fn exists(&self, name: &str) -> Option<usize> {
for pos in 0..self.attrs.len() {
if &self.attrs[pos].name == name {
return Some(pos)
}
}
None
}
pub fn exists_ok(&self, name: &str) -> Result<usize, DBError> {
self.exists(name)
.ok_or(DBError::AttributeMissing(format!("(name: {})", name)))
}
pub fn get(&self, pos: usize) -> Result<&Attribute, DBError> {
if pos >= self.attrs.len() {
Err(DBError::AttributeMissing(format!("(pos: {})", pos)))
} else {
Ok(&self.attrs[pos])
}
}
pub fn find(&self, name: &str) -> Result<&Attribute, DBError> {
for attr in &self.attrs {
if &attr.name == name {
return Ok(attr)
}
}
Err(DBError::AttributeMissing(format!("(name: {})", name)))
}
pub fn iter(&self) -> AttributeIter {
AttributeIter { schema: self, cur: 0 }
}
}
impl<'a> Iterator for AttributeIter<'a> {
type Item = &'a Attribute;
fn next(&mut self) -> Option<&'a Attribute> {
let r = if self.cur >= self.schema.attrs.len() {
return None
} else {
&self.schema.attrs[self.cur]
};
self.cur += 1;
Some(r)
}
}