rest_api/database/
interfaces.rs
1use std::collections::HashMap;
2use std::path::Path;
3use std::fs;
4
5use super::table_schema::SqlTableSchema;
6use super::response::{Sqlite3ResponseBuilder, ResponseBuilder};
7use super::query::{Sqlite3Query, Query};
8
9use sqlite3::{open, Connection};
10use hyper::{Body, Request, Response};
11
12#[derive(Clone, Debug)]
13pub enum SQLType {
14 Null,
15 Integer,
16 Real,
17 Text,
18}
19
20
21type Config = HashMap<String, String>;
22
23#[async_trait::async_trait]
24pub trait DatabaseInterface {
25 fn connect(config: &Config) -> (Self, bool)
27 where Self: Sized;
28 fn delete_db(config: &Config)
29 where Self: Sized;
30
31 fn create_tables_from_schemas(&self, schemas: Vec<&SqlTableSchema>) {
32 for schema in schemas {
33 self.table_from_types(schema.name.clone(), &schema.fields)
34 }
35 }
36
37 fn table_from_types(&self, table_name: String, types: &HashMap<String, SQLType>);
38 async fn process_api_request(&self, request: &mut Request<Body>, table: &SqlTableSchema) -> Response<Body>;
39}
40
41pub struct SQLite3Interface {
42 connection: Connection,
43}
44
45#[async_trait::async_trait]
46impl DatabaseInterface for SQLite3Interface {
47 fn connect(config: &Config) -> (Self, bool) {
48 let db_path = config.get("database_path").expect("Can't find 'database_path' config");
49
50 let existing = Path::new(db_path).exists();
51
52 let connection = open(db_path).expect(&format!("Can't open sqlite3 database at: {}", db_path));
53
54 log::info!("Connected to database at {}", db_path);
55 (
56 Self {
57 connection
58 }
59 , existing
60 )
61 }
62
63 fn table_from_types(&self, table_name: String, types: &HashMap<String, SQLType>) {
64 let mut sql = format!("CREATE TABLE IF NOT EXISTS {} (ID INTEGER PRIMARY KEY,", table_name);
65
66 for (col_name, data_type) in types {
67 sql.push_str(&col_name);
68 let dtype = match data_type {
69 SQLType::Null => " NULL",
70 SQLType::Integer => " INTEGER",
71 SQLType::Real => " REAL",
72 SQLType::Text => " TEXT",
73 };
74 sql.push_str(dtype);
75 sql.push_str(", ")
76 }
77 sql.remove(sql.len()-1);
79 sql.remove(sql.len()-1);
80 sql.push_str(");");
81
82 log::info!("Creating table with SQL: {}", sql);
83
84 self.connection.execute(sql).expect("Can't create table");
85 }
86
87 fn delete_db(config: &Config) {
88 let db_path = config.get("database_path").expect("Can't find 'database_path' config");
89 let result = fs::remove_file(db_path);
90
91 match result {
92 Ok(_) => log::info!("Deleted sqlite3 database"),
93 Err(e) => log::error!("Error when deleting sqlite3 database: {}", e)
94 }
95 }
96
97 async fn process_api_request(&self, request: &mut Request<Body>, table: &SqlTableSchema) -> Response<Body> {
98 let query = Sqlite3Query::from_request(request, table).await;
100
101 if query.is_err() {
102 let error = query.err().unwrap();
103
104 if error.1 {
105 log::warn!("{}", error.0);
106 return Response::builder()
107 .status(500)
108 .body(Body::from("Server Error Encountered"))
109 .unwrap();
110 } else {
111 log::debug!("{}", error.0);
112 return Response::builder()
113 .status(400)
114 .body(Body::from("Client Error"))
115 .unwrap();
116 }
117 }
118
119 let query = query.unwrap();
121 let cursor = query.execute_sql(&self.connection);
122
123 if cursor.is_err() {
124 let error = cursor.err().unwrap();
125 log::warn!("{}", error);
126
127 return Response::builder()
128 .status(500)
129 .body(Body::from("Server Error Encountered"))
130 .unwrap();
131 }
132
133 let mut all_data = Vec::new();
135 let mut c = cursor.unwrap();
136 while let Ok(Some(d)) = c.next() {
137 all_data.push(d.to_vec())
138 }
139
140 let response_json_text = Sqlite3ResponseBuilder::from_row_data(all_data);
141 Response::new(Body::from(response_json_text))
142 }
143}
144
145unsafe impl Send for SQLite3Interface {}
148unsafe impl Sync for SQLite3Interface {}