aragog/db/
database_connection_builder.rs1#![allow(clippy::redundant_pub_crate)]
2use std::convert::{TryFrom, TryInto};
3
4use crate::schema::{DatabaseSchema, SCHEMA_DEFAULT_FILE_NAME, SCHEMA_DEFAULT_PATH};
5use crate::{AuthMode, DatabaseConnection, Error, OperationOptions};
6
7#[derive(Debug, Clone)]
8pub(crate) struct DbCredentials {
9 db_host: String,
10 db_name: String,
11 db_user: String,
12 db_password: String,
13}
14
15#[derive(Debug, Clone)]
16pub(crate) enum DbCredentialsOption {
17 Auto,
18 Custom(DbCredentials),
19}
20
21#[derive(Debug)]
22pub(crate) enum DatabaseSchemaOption {
23 Auto,
24 Path(String),
25 Custom(DatabaseSchema),
26}
27
28impl From<DbCredentialsOption> for DbCredentials {
29 fn from(option: DbCredentialsOption) -> Self {
30 match option {
31 DbCredentialsOption::Custom(cred) => cred,
32 DbCredentialsOption::Auto => Self {
33 db_host: std::env::var("DB_HOST").expect("Please define DB_HOST env var."),
34 db_name: std::env::var("DB_NAME").expect("Please define DB_NAME env var."),
35 db_user: std::env::var("DB_USER").expect("Please define DB_USER env var."),
36 db_password: std::env::var("DB_PASSWORD")
37 .expect("Please define DB_PASSWORD env var."),
38 },
39 }
40 }
41}
42
43impl TryFrom<DatabaseSchemaOption> for DatabaseSchema {
44 type Error = Error;
45
46 fn try_from(option: DatabaseSchemaOption) -> Result<Self, Self::Error> {
47 match option {
48 DatabaseSchemaOption::Custom(schema) => Ok(schema),
49 DatabaseSchemaOption::Path(path) => Self::load(&path),
50 DatabaseSchemaOption::Auto => {
51 let schema_path = match std::env::var("SCHEMA_PATH") {
52 Ok(path) => path,
53 Err(_err) => {
54 log::debug!(
55 "Missing SCHEMA_PATH env var, using default value: {}",
56 SCHEMA_DEFAULT_PATH
57 );
58 SCHEMA_DEFAULT_PATH.to_string()
59 }
60 };
61 Self::load(&format!("{}/{}", schema_path, SCHEMA_DEFAULT_FILE_NAME))
62 }
63 }
64 }
65}
66
67pub struct DatabaseConnectionBuilder {
69 pub(crate) apply_schema: bool,
70 pub(crate) auth_mode: AuthMode,
71 pub(crate) credentials: DbCredentialsOption,
72 pub(crate) schema: DatabaseSchemaOption,
73 pub(crate) operation_options: OperationOptions,
74}
75
76impl DatabaseConnectionBuilder {
77 #[maybe_async::maybe_async]
106 pub async fn build(self) -> Result<DatabaseConnection, Error> {
107 let credentials = self.credentials();
108 let auth_mode = self.auth_mode();
109 let apply_schema = self.apply_schema;
110 let operation_options = self.operation_options.clone();
111 let schema = self.schema()?;
112 let database = DatabaseConnection::connect(
113 &credentials.db_host,
114 &credentials.db_name,
115 &credentials.db_user,
116 &credentials.db_password,
117 auth_mode,
118 )
119 .await?;
120 DatabaseConnection::new(database, schema, apply_schema, operation_options).await
121 }
122
123 #[must_use]
127 #[inline]
128 pub fn with_auth_mode(mut self, mode: AuthMode) -> Self {
129 log::debug!(
130 "[Database Connection Builder] Auth mode {:?} will be used",
131 mode
132 );
133 self.auth_mode = mode;
134 self
135 }
136
137 #[must_use]
146 #[inline]
147 pub fn with_credentials(
148 mut self,
149 db_host: &str,
150 db_name: &str,
151 db_user: &str,
152 db_password: &str,
153 ) -> Self {
154 log::debug!(
155 "[Database Connection Builder] Custom credentials for `ArangoDB` host {} will be used",
156 db_host
157 );
158 self.credentials = DbCredentialsOption::Custom(DbCredentials {
159 db_host: String::from(db_host),
160 db_name: String::from(db_name),
161 db_user: String::from(db_user),
162 db_password: String::from(db_password),
163 });
164 self
165 }
166
167 #[must_use]
171 #[inline]
172 pub fn with_schema(mut self, schema: DatabaseSchema) -> Self {
173 log::debug!("[Database Connection Builder] Custom schema will be used");
174 self.schema = DatabaseSchemaOption::Custom(schema);
175 self
176 }
177
178 #[must_use]
183 #[inline]
184 pub fn apply_schema(mut self) -> Self {
185 log::debug!("[Database Connection Builder] Schema will be silently applied");
186 self.apply_schema = true;
187 self
188 }
189
190 #[must_use]
194 #[inline]
195 pub fn with_schema_path(mut self, path: &str) -> Self {
196 log::debug!(
197 "[Database Connection Builder] Schema from {} will be used",
198 path
199 );
200 self.schema = DatabaseSchemaOption::Path(String::from(path));
201 self
202 }
203
204 #[must_use]
215 #[inline]
216 pub fn with_operation_options(mut self, options: OperationOptions) -> Self {
217 log::debug!(
218 "[Database Connection Builder] custom operation options will be used: {:?}",
219 options
220 );
221 self.operation_options = options;
222 self
223 }
224
225 #[must_use]
226 #[inline]
227 fn credentials(&self) -> DbCredentials {
228 self.credentials.clone().into()
229 }
230
231 fn schema(self) -> Result<DatabaseSchema, Error> {
232 self.schema.try_into()
233 }
234
235 #[must_use]
236 #[inline]
237 const fn auth_mode(&self) -> AuthMode {
238 self.auth_mode
239 }
240}