Skip to content

Commit

Permalink
feat(driver-adapters): enable Wasm on request-handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jkomyno committed Nov 15, 2023
1 parent e66fb65 commit b69bb84
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 82 deletions.
9 changes: 5 additions & 4 deletions query-engine/request-handlers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ edition = "2021"

[dependencies]
prisma-models = { path = "../prisma-models" }
query-core = { path = "../core", features = ["metrics"] }
query-core = { path = "../core" }
user-facing-errors = { path = "../../libs/user-facing-errors" }
quaint = { path = "../../quaint" }
psl.workspace = true
dmmf_crate = { path = "../dmmf", package = "dmmf" }
itertools = "0.10"
Expand All @@ -20,7 +21,6 @@ thiserror = "1"
tracing = "0.1"
url = "2"
connection-string.workspace = true
quaint.workspace = true
once_cell = "1.15"

mongodb-query-connector = { path = "../connectors/mongodb-query-connector", optional = true }
Expand All @@ -32,10 +32,11 @@ schema = { path = "../schema" }
codspeed-criterion-compat = "1.1.0"

[features]
default = ["mongodb", "sql"]
default = ["sql", "mongodb", "native"]
mongodb = ["mongodb-query-connector"]
sql = ["sql-query-connector"]
driver-adapters = ["sql-query-connector"]
driver-adapters = ["sql-query-connector/driver-adapters"]
native = ["mongodb", "sql-query-connector", "quaint/native", "query-core/metrics"]

[[bench]]
name = "query_planning_bench"
Expand Down
1 change: 1 addition & 0 deletions query-engine/request-handlers/src/connector_mode.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConnectorMode {
/// Indicates that Rust drivers are used in Query Engine.
#[cfg(feature = "native")]
Rust,

/// Indicates that JS drivers are used in Query Engine.
Expand Down
162 changes: 84 additions & 78 deletions query-engine/request-handlers/src/load_executor.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#![allow(unused_imports)]

use psl::{builtin_connectors::*, Datasource, PreviewFeatures};
use query_core::{executor::InterpretingExecutor, Connector, QueryExecutor};
use sql_query_connector::*;
use std::collections::HashMap;
use std::env;
use tracing::trace;
use url::Url;

#[cfg(feature = "mongodb")]
use mongodb_query_connector::MongoDb;

use super::ConnectorMode;

/// Loads a query executor based on the parsed Prisma schema (datasource).
Expand All @@ -27,6 +25,7 @@ pub async fn load(
driver_adapter(source, url, features).await
}

#[cfg(feature = "native")]
ConnectorMode::Rust => {
if let Ok(value) = env::var("PRISMA_DISABLE_QUAINT_EXECUTORS") {
let disable = value.to_uppercase();
Expand All @@ -36,14 +35,14 @@ pub async fn load(
}

match source.active_provider {
p if SQLITE.is_provider(p) => sqlite(source, url, features).await,
p if MYSQL.is_provider(p) => mysql(source, url, features).await,
p if POSTGRES.is_provider(p) => postgres(source, url, features).await,
p if MSSQL.is_provider(p) => mssql(source, url, features).await,
p if COCKROACH.is_provider(p) => postgres(source, url, features).await,
p if SQLITE.is_provider(p) => native::sqlite(source, url, features).await,
p if MYSQL.is_provider(p) => native::mysql(source, url, features).await,
p if POSTGRES.is_provider(p) => native::postgres(source, url, features).await,
p if MSSQL.is_provider(p) => native::mssql(source, url, features).await,
p if COCKROACH.is_provider(p) => native::postgres(source, url, features).await,

#[cfg(feature = "mongodb")]
p if MONGODB.is_provider(p) => mongodb(source, url, features).await,
p if MONGODB.is_provider(p) => native::mongodb(source, url, features).await,

x => Err(query_core::CoreError::ConfigurationError(format!(
"Unsupported connector type: {x}"
Expand All @@ -53,57 +52,88 @@ pub async fn load(
}
}

async fn sqlite(
#[cfg(feature = "driver-adapters")]
async fn driver_adapter(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading SQLite query connector...");
let sqlite = Sqlite::from_source(source, url, features).await?;
trace!("Loaded SQLite query connector.");
Ok(executor_for(sqlite, false))
) -> Result<Box<dyn QueryExecutor + Send + Sync>, query_core::CoreError> {
let js = Js::from_source(source, url, features).await?;
Ok(executor_for(js, false))
}

async fn postgres(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading Postgres query connector...");
let database_str = url;
let psql = PostgreSql::from_source(source, url, features).await?;

let url = Url::parse(database_str)
.map_err(|err| query_core::CoreError::ConfigurationError(format!("Error parsing connection string: {err}")))?;
let params: HashMap<String, String> = url.query_pairs().into_owned().collect();

let force_transactions = params
.get("pgbouncer")
.and_then(|flag| flag.parse().ok())
.unwrap_or(false);
trace!("Loaded Postgres query connector.");
Ok(executor_for(psql, force_transactions))
}
#[cfg(feature = "native")]
mod native {
use super::*;
use tracing::trace;

pub(crate) async fn sqlite(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading SQLite query connector...");
let sqlite = Sqlite::from_source(source, url, features).await?;
trace!("Loaded SQLite query connector.");
Ok(executor_for(sqlite, false))
}

async fn mysql(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
let mysql = Mysql::from_source(source, url, features).await?;
trace!("Loaded MySQL query connector.");
Ok(executor_for(mysql, false))
}
pub(crate) async fn postgres(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading Postgres query connector...");
let database_str = url;
let psql = PostgreSql::from_source(source, url, features).await?;

let url = Url::parse(database_str).map_err(|err| {
query_core::CoreError::ConfigurationError(format!("Error parsing connection string: {err}"))
})?;
let params: HashMap<String, String> = url.query_pairs().into_owned().collect();

let force_transactions = params
.get("pgbouncer")
.and_then(|flag| flag.parse().ok())
.unwrap_or(false);
trace!("Loaded Postgres query connector.");
Ok(executor_for(psql, force_transactions))
}

async fn mssql(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading SQL Server query connector...");
let mssql = Mssql::from_source(source, url, features).await?;
trace!("Loaded SQL Server query connector.");
Ok(executor_for(mssql, false))
pub(crate) async fn mysql(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
let mysql = Mysql::from_source(source, url, features).await?;
trace!("Loaded MySQL query connector.");
Ok(executor_for(mysql, false))
}

pub(crate) async fn mssql(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading SQL Server query connector...");
let mssql = Mssql::from_source(source, url, features).await?;
trace!("Loaded SQL Server query connector.");
Ok(executor_for(mssql, false))
}

#[cfg(feature = "mongodb")]
pub(crate) async fn mongodb(
source: &Datasource,
url: &str,
_features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
use mongodb_query_connector::MongoDb;

trace!("Loading MongoDB query connector...");
let mongo = MongoDb::new(source, url).await?;
trace!("Loaded MongoDB query connector.");
Ok(executor_for(mongo, false))
}
}

fn executor_for<T>(connector: T, force_transactions: bool) -> Box<dyn QueryExecutor + Send + Sync>
Expand All @@ -112,27 +142,3 @@ where
{
Box::new(InterpretingExecutor::new(connector, force_transactions))
}

#[cfg(feature = "mongodb")]
async fn mongodb(
source: &Datasource,
url: &str,
_features: PreviewFeatures,
) -> query_core::Result<Box<dyn QueryExecutor + Send + Sync>> {
trace!("Loading MongoDB query connector...");
let mongo = MongoDb::new(source, url).await?;
trace!("Loaded MongoDB query connector.");
Ok(executor_for(mongo, false))
}

#[cfg(feature = "driver-adapters")]
async fn driver_adapter(
source: &Datasource,
url: &str,
features: PreviewFeatures,
) -> Result<Box<dyn QueryExecutor + Send + Sync>, query_core::CoreError> {
trace!("Loading driver adapter...");
let js = Js::from_source(source, url, features).await?;
trace!("Loaded driver adapter...");
Ok(executor_for(js, false))
}

0 comments on commit b69bb84

Please sign in to comment.