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
use crate::manager::pool::{Pool, PoolError};
use crate::sql::parser::{Parser, ParserError};
use crate::storage::diskinterface::{DiskError, DiskInterface};
use crate::Response;
use std::fmt;
use std::sync::{Arc, Mutex};
#[derive(Debug)]
pub struct Request {
pub username: String,
pub addr: String,
pub key: i32,
}
#[derive(Debug)]
pub enum RequestError {
PoolError(PoolError),
CauseByParser(ParserError),
DiskError(DiskError),
UserNotExist(String),
CreateDBBeforeCmd,
BadRequest,
InvalidKey,
}
impl fmt::Display for RequestError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RequestError::PoolError(ref e) => write!(f, "error caused by pool: {}", e),
RequestError::CauseByParser(ref e) => write!(f, "error caused by parser: {}", e),
RequestError::DiskError(ref e) => write!(f, "error caused by file: {}", e),
RequestError::UserNotExist(ref s) => write!(f, "user: {} not found", s),
RequestError::CreateDBBeforeCmd => write!(f, "please create a database before any other commands"),
RequestError::BadRequest => write!(f, "BadRequest, invalid request format"),
RequestError::InvalidKey => write!(f, "invalid key format"),
}
}
}
impl Request {
pub fn new(new_addr: String) -> Request {
Request {
username: "".to_string(),
addr: new_addr,
key: 0,
}
}
pub fn parse(input: &str, mutex: &Arc<Mutex<Pool>>, req: &mut Request) -> Result<Response, RequestError> {
let split_str: Vec<&str> = input.split("||").collect();
if req.username == "" {
if split_str.len() != 4 || split_str[1] != "" || split_str[2] != "" {
return Err(RequestError::BadRequest);
}
let username = split_str[0];
let key: i32 = match split_str[3].parse() {
Ok(_key) => _key,
Err(_) => return Err(RequestError::InvalidKey),
};
req.key = key;
match Request::user_verify(username) {
Ok(()) => req.username = username.to_string(),
Err(ret) => return Err(ret),
}
return Ok(Response::OK {
msg: "Login OK!".to_string(),
});
}
if split_str.len() != 3 {
return Err(RequestError::BadRequest);
}
let username = split_str[0];
let dbname = split_str[1];
let cmd = format!("{};", split_str[2]);
let mut pool = mutex.lock().unwrap();
let mut sql = match pool.get(username, dbname, req.addr.clone()) {
Ok(tsql) => tsql,
Err(ret) => return Err(RequestError::PoolError(ret)),
};
if sql.user.key == 0 {
sql.user.key = req.key;
}
if dbname != "" {
let parser = match Parser::new(&cmd) {
Ok(_parser) => _parser,
Err(ret) => return Err(RequestError::CauseByParser(ret)),
};
match parser.parse(&mut sql) {
Err(ret) => return Err(RequestError::CauseByParser(ret)),
Ok(_) => {}
}
} else {
let mut iter = cmd.split_whitespace();
if iter.next() != Some("create") || iter.next() != Some("database") {
return Err(RequestError::CreateDBBeforeCmd);
}
let parser = match Parser::new(&cmd) {
Ok(_parser) => _parser,
Err(ret) => return Err(RequestError::CauseByParser(ret)),
};
match parser.parse(&mut sql) {
Err(ret) => return Err(RequestError::CauseByParser(ret)),
Ok(_) => {}
}
}
if !sql.result_json.is_empty() {
let return_json = sql.result_json.clone();
sql.result_json.clear();
return Ok(Response::OK {
msg: return_json.to_string(),
});
}
Ok(Response::OK {
msg: "Query OK!".to_string(),
})
}
fn user_verify(name: &str) -> Result<(), RequestError> {
if name == "" {
return Err(RequestError::UserNotExist(name.to_string()));
} else {
let users = match DiskInterface::get_usernames(Some(dotenv!("FILE_BASE_PATH"))) {
Ok(us) => us,
Err(ret) => return Err(RequestError::DiskError(ret)),
};
if !users.contains(&name.to_string()) {
match DiskInterface::create_username(name, Some(dotenv!("FILE_BASE_PATH"))) {
Ok(_) => {}
Err(ret) => return Err(RequestError::DiskError(ret)),
}
}
}
Ok(())
}
}