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
use std::collections::HashMap;
use std::fs;
use arangors::{Collection, Connection, Database};
use arangors::client::reqwest::ReqwestClient;
use serde_json::Value;
use crate::helpers::{json_helper};
use crate::db::database_collection::DatabaseCollection;
const SCHEMA_DEFAULT_PATH: &str = "./src/config/db/schema.json";
const SCHEMA_COLLECTION_KEY: &str = "collections";
const SCHEMA_COLLECTION_NAME: &str = "name";
#[derive(Clone)]
pub struct DatabaseConnectionPool {
pub collections: HashMap<String, DatabaseCollection>,
pub database: Database<ReqwestClient>,
}
impl DatabaseConnectionPool {
pub async fn new(db_host: &str, db_name :&str, db_user: &str, db_password: &str) -> Self {
log::info!("Connecting to database server...");
let db_connection = Connection::establish_basic_auth(
db_host,
db_user,
db_password).await.unwrap();
log::info!("Connected to database server.");
let database = db_connection.db(&db_name).await.unwrap();
let collections = DatabaseConnectionPool::load_schema(&database).await.unwrap();
DatabaseConnectionPool { collections, database }
}
pub fn get_collection(&self, collection: &str) -> &Collection<ReqwestClient> {
&self.collections[collection].collection
}
pub async fn truncate(&self) {
for collection in self.collections.iter() {
collection.1.collection.truncate().await.unwrap();
}
}
async fn load_schema(database: &Database<ReqwestClient>) -> Result<HashMap<String, DatabaseCollection>, String> {
let schema_path = match std::env::var("SCHEMA_PATH") {
Ok(path) => path,
Err(_err) => SCHEMA_DEFAULT_PATH.to_string()
};
let file = fs::File::open(&schema_path).expect(&format!("{} doesn't open correctly", &schema_path));
let json: Value = serde_json::from_reader(file).expect(&format!("{} is not formatted correctly", &schema_path));
let mut json_collections: Vec<Value> = Vec::new();
if let Value::Array(values) = &json[SCHEMA_COLLECTION_KEY] {
json_collections = values.clone();
}
let mut collections_map = HashMap::new();
for json_collection in json_collections {
let collection_name =
json_helper::load_json_string_key(&json_collection, &SCHEMA_COLLECTION_NAME)?;
let collection: Collection<ReqwestClient>;
match database.collection(&collection_name).await {
Ok(coll) => {
collection = coll
}
Err(_error) => {
log::info!("Collection {} not found, creating...", &collection_name);
collection = database.create_collection(&collection_name).await.unwrap()
}
}
let collection_container = DatabaseCollection {
collection_name,
collection,
};
Self::handle_index(database, json_collection, &collection_container).await?;
collections_map.insert(collection_container.collection_name.clone(), collection_container);
}
Ok(collections_map)
}
async fn handle_index(database: &Database<ReqwestClient>, json_collection: Value, collection: &DatabaseCollection) -> Result<(), String> {
let indexes = json_collection["indexes"].as_array().unwrap();
for index in indexes {
let index = DatabaseCollection::index_from_json(index)?;
if collection.index_exists(database, &index).await.unwrap() {
log::info!("Index {} exists, skipping...", index.name);
continue;
}
log::info!("Index {} not found, creating...", index.name);
database.create_index(&collection.collection_name, &index).await.unwrap();
}
Ok(())
}
}