-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
efficient DB connection & query cache (#72)
* cleanup * chore: cache fetch table result in information_schema * chore: fmt * chore: refactoring inefficient connection logic * wip * wip: postgres need to be using an async client * works * wip: saving changes for now - going to try connection pooling * chore: moving connection init to static lifetime scope * chore: lazy connection fixed * chore: clean up * chore: fix test * chore: clippy * chore: cleanup * chore: clean up * chore: add information on DB_CONN_CACHE lazy static * chore: remove SOME_INT * chore: add docs on DB_CONNECTIONS * chore: clean up * chore: cleanup unused imports * chore: clean up
- Loading branch information
Showing
20 changed files
with
212 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,52 @@ | ||
use crate::common::cli::Cli; | ||
use crate::common::config::Config; | ||
use crate::common::types::DatabaseType; | ||
use crate::core::connection::{DBConn, DBConnections}; | ||
use crate::ts_generator::information_schema::DBSchema; | ||
use clap::Parser; | ||
use lazy_static::lazy_static; | ||
use mysql::Conn as MySQLConn; | ||
use postgres::{Client as PGClient, NoTls as PGNoTls}; | ||
use std::collections::HashMap; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
// The file contains all implicitly dependent variables or state that files need for the logic | ||
// We have a lot of states that we need to drill down into each methods | ||
lazy_static! { | ||
pub static ref SOME_INT: i32 = 5; | ||
|
||
pub static ref CLI_ARGS: Cli = Cli::parse(); | ||
pub static ref CONFIG: Config = Config::new(); | ||
|
||
// This is a holder for shared DBSChema used to fetch information for information_schema table | ||
// By having a singleton, we can think about caching the result if we are fetching a query too many times | ||
pub static ref DB_SCHEMA: DBSchema = DBSchema::new(); | ||
pub static ref DB_SCHEMA: Mutex<DBSchema> = Mutex::new(DBSchema::new()); | ||
|
||
// This variable holds database connections for each connection name that is defined in the config | ||
// We are using lazy_static to initialize the connections once and use them throughout the application | ||
static ref DB_CONN_CACHE: HashMap<String, Arc<Mutex<DBConn>>> = { | ||
let mut cache = HashMap::new(); | ||
for connection in CONFIG.connections.keys() { | ||
let connection_config = CONFIG.connections.get(connection).unwrap(); | ||
let db_type = connection_config.db_type.to_owned(); | ||
let conn = match db_type { | ||
DatabaseType::Mysql => { | ||
let opts = CONFIG.get_mysql_cred(&connection_config); | ||
let mut conn = MySQLConn::new(opts).unwrap(); | ||
DBConn::MySQLPooledConn(Mutex::new(conn)) | ||
} | ||
DatabaseType::Postgres => { | ||
let postgres_cred = &CONFIG.get_postgres_cred(&connection_config); | ||
DBConn::PostgresConn(Mutex::new(PGClient::connect(postgres_cred, PGNoTls).unwrap())) | ||
} | ||
}; | ||
cache.insert(connection.to_owned(), Arc::new(Mutex::new(conn))); | ||
}; | ||
cache | ||
}; | ||
|
||
// This variable holds a singleton of DBConnections that is used to get a DBConn from the cache | ||
// DBConn is used to access the raw connection to the database or run `prepare` statement against each connection | ||
pub static ref DB_CONNECTIONS: Mutex<DBConnections<'static>> = { | ||
let db_connections = DBConnections::new(&DB_CONN_CACHE); | ||
Mutex::new(db_connections) | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use crate::common::lazy::CONFIG; | ||
use crate::common::SQL; | ||
use crate::core::mysql::prepare as mysql_explain; | ||
use crate::core::postgres::prepare as postgres_explain; | ||
use crate::ts_generator::types::ts_query::TsQuery; | ||
use std::collections::HashMap; | ||
use std::sync::Arc; | ||
use std::sync::Mutex; | ||
|
||
use color_eyre::Result; | ||
use mysql::Conn as MySQLConn; | ||
use postgres::Client as PostgresConn; | ||
use swc_common::errors::Handler; | ||
|
||
/// Enum to hold a specific database connection instance | ||
pub enum DBConn { | ||
MySQLPooledConn(Mutex<MySQLConn>), | ||
PostgresConn(Mutex<PostgresConn>), | ||
} | ||
|
||
impl DBConn { | ||
pub fn prepare( | ||
&self, | ||
sql: &SQL, | ||
should_generate_types: &bool, | ||
handler: &Handler, | ||
) -> Result<(bool, Option<TsQuery>)> { | ||
let (explain_failed, ts_query) = match &self { | ||
DBConn::MySQLPooledConn(_conn) => mysql_explain::prepare(&self, sql, should_generate_types, handler)?, | ||
DBConn::PostgresConn(_conn) => postgres_explain::prepare(&self, sql, should_generate_types, handler)?, | ||
}; | ||
|
||
Ok((explain_failed, ts_query)) | ||
} | ||
} | ||
|
||
pub struct DBConnections<'a> { | ||
pub cache: &'a HashMap<String, Arc<Mutex<DBConn>>>, | ||
} | ||
|
||
impl<'a> DBConnections<'a> { | ||
pub fn new(cache: &'a HashMap<String, Arc<Mutex<DBConn>>>) -> Self { | ||
Self { cache } | ||
} | ||
|
||
pub fn get_connection(&mut self, raw_sql: &str) -> Arc<Mutex<DBConn>> { | ||
let db_conn_name = &CONFIG.get_correct_db_connection(raw_sql); | ||
|
||
let conn = self | ||
.cache | ||
.get(db_conn_name) | ||
.expect("Failed to get the connection from cache"); | ||
conn.to_owned() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod connection; | ||
pub mod execute; | ||
pub mod mysql; | ||
pub mod postgres; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.