-
Notifications
You must be signed in to change notification settings - Fork 0
/
database.rs
156 lines (115 loc) · 3.44 KB
/
database.rs
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
// this module will contain the data access operations and the data model.
use std::collections::HashMap;
use std::hash::Hash;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt;
const DUPLICATED_ROW:&str="Duplicated row: there is already a {} with this {}" ;
#[derive(Eq,PartialEq,Hash,Debug,Clone)]
struct IdMapping {
key: u64,
value: u64,
}
impl Display for IdMapping {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Use `self.number` to refer to each positional data point.
write!(f, "({}, {})", self.key, self.value)
}
}
struct Database {
employees: Table<&'static str>,
departments: Table<&'static str>,
employee_vs_department: Table<IdMapping>,
}
#[derive(Eq,PartialEq,Hash,Debug)]
struct Row<T:Display + Debug> {
id: u64,
value: T
}
struct Table<T:Eq + PartialEq + Hash + Clone + Display + Debug> {
next_primary_key: u64,
row_id_by_name: HashMap<T,u64>,
rows_by_id: HashMap<u64,Row<T>>,
name: String
}
impl<T:Eq + PartialEq + Hash + Clone + Display +Debug > Table<T> {
fn new(name:&str) -> Self {
Table {
next_primary_key: 0,
rows_by_id: HashMap::new(),
row_id_by_name:HashMap::new(),
name: String::from(name)
}
}
fn insert(&mut self,value2: T) -> Result<u64,String> {
let id2 = self.next_primary_key;
if let Some(existing) = self.row_id_by_name.get(&value2) {
return Err(String::from(format!("Value {} already exists in the database as row {:?}",value2,existing)));
};
self.next_primary_key+=1;
let row = Row {
id:id2,
value:value2.clone()
};
let valueKey = row.value.clone();
self.rows_by_id.insert(id2,row);
self.row_id_by_name.insert(valueKey,id2);
Ok(id2)
}
// dele
fn update(&mut self) -> Result<Row<T>,&str> {
Err("boom!")
}
// delete a row by name
fn delete_by_data(&mut self,row: T ) -> Result<u64,&str> {
Err("boom!")
}
fn delete_by_id(&mut self,id: u64) -> Result<u64,&str> {
Err("boom!")
}
// find a row with the provided name.
fn find(&self,name: T) -> Option<Row<T>> {
None
}
}
#[cfg(test)]
mod tests {
use crate::database::*;
#[test]
fn test_table() {
let mut the_table: Table<String> = Table::new("my_table");
// making the test to happen in an inner scope. Will the string references survive?
{
let tommy1 = String::from("Tommy");
let value = the_table.insert(tommy1).expect("Since this is an empty table, the first row should be accepted automatically");
assert_eq!(0,value);
};
{
let tommy2 = String::from("Tommy");
let response = the_table.insert(tommy2);
if let Err(ref msg) = response {
println!("{}",msg);
}
assert!(response.is_err(),"Adding a new row with the same name should return an error");
};
let found_tommy = the_table.find(String::from("Tommy"));
assert!(found_tommy.is_some() , "The find function should find Tommy under id 0");
}
#[test]
fn test_table_with_str<'a>() {
let mut the_table: Table<&'a str> = Table::new("my_table");
{
let tommy1:&'a str = String::from("Tommy").leak();
let value = the_table.insert(tommy1).expect("Since this is an empty table, the first row should be accepted automatically");
assert_eq!(0,value);
};
{
let tommy2:&'a str = String::from("Tommy").leak();
let response = the_table.insert(tommy2);
if let Err(ref msg) = response {
println!("{}",msg);
}
assert!(response.is_err(),"Adding a new row with the same name should return an error");
};
}
}